我已经使用C编程语言创建了一个命令行实用程序。现在我想将该命令嵌入到bash中。它应该作为bash内置命令'cd'。 我该怎么做?如何将命令嵌入到作为内置的bash中?
在bash源文件中,我看到有一个目录builtins
。我看了那个目录,发现有*.def
文件,还有一个文件叫cd.def
。
我认为这是bash内置的定义cd
。现在我的问题是如何创建我自己的定义?
我已经使用C编程语言创建了一个命令行实用程序。现在我想将该命令嵌入到bash中。它应该作为bash内置命令'cd'。 我该怎么做?如何将命令嵌入到作为内置的bash中?
在bash源文件中,我看到有一个目录builtins
。我看了那个目录,发现有*.def
文件,还有一个文件叫cd.def
。
我认为这是bash内置的定义cd
。现在我的问题是如何创建我自己的定义?
如果你想使你的二进制内置在bash
方法1:bash函数
您可以通过创建一个bash函数模仿行为,说~/.bashrc
,文件:
function mycommand
{
/path/to/your/binary #plus arguments if any
}
export -f mycommand
和使用mycommand
就像你使用cd
。
看看这[ tldp article ]如何这不同于实际的内置。
方法2:使用使
我想我会通过创建寻找阶乘一个新的内置证明这一点。下面是我写的代码:
/* Programme to compute the factorial of numbers up to 60 */
#include <bash/config.h>
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <bash/shell.h> // for shell internals
#include <bash/builtins.h> // for struct builtin
#include <stdio.h>
#include <stdlib.h> // for atoi
/* For unsigned long long numbers, my system could handle numbers
* upto 65 when it comes to factorial, but I'm restricting the value
* to 60 for the sake of the example so naming my builtin 'factorial60'
* the wrapper is factorial_wrapper and the actual task of computing the
* factorial is done by the function 'factorial'which resides inside the
* wrapper.
*/
unsigned long long factorial(unsigned long long x, unsigned long long amt)
{
if (x == 0)
return amt;
else
amt*=x;
return factorial(x-1, amt);
}
int factorial_wrapper(WORD_LIST* list) //Wrapper function
{
char* ptr=NULL;
int num;
if (list == 0) {
builtin_usage();
fflush(stdout);
return (EX_USAGE);
}
else{
ptr=list->word->word;
/* We're expecting one & only one argument here.
* I haven't checked for multiple arguments for the sake of brevity
*/
num=atoi(ptr);
/* atoi is not the best here because it returns zero for invalid conversions
* I used it just for the sake of this example.
*/
if (num>60){
builtin_usage();
fflush(stdout);
return (EX_USAGE);
}
printf("%llu\n",factorial(num,1));
fflush(stdout);
}
return (EXECUTION_SUCCESS); // returning 0
}
char *factorial60_doc[] = {
"factorial60",
"Usage : factorial60 number",
"Description :",
"Gives the factorial of numbers upto 60",
(char *)NULL
};
// Make sure the above documentation is sensible
// You need to supply factorial60_doc to the structure below.
struct builtin factorial60_struct = {
"factorial60", // builtin name
factorial_wrapper, // wrapper function for implementing the builtin
BUILTIN_ENABLED, // initial flags for builtin - See Reference 1
factorial60_doc, // array of long documentation strings.
"Usage : factorial60 'number_upto_60'", // usage synopsis; becomes short_doc
NULL // reserved for internal use, this a char*
};
编译像下面的代码:
gcc -shared -fpic -o factorial.so factorial.c
复制共享对象factorial.so对本地的lib位置说/usr/local/lib/mylib/
启用(通过在〜/ .bashrc中添加下面的内容(或者/etc/bash.bashrc,如果您希望其他用户使用新的内置函数),新的内置函数将被添加到内存中:
enable -f /usr/local/lib/mylib/factorial.so factorial60 # You need to give the full path
瞧!你已经准备好在新的shell会话中使用新内置。
$ factorial60 24
10611558092380307456
$ factorial60
factorial60: usage: Usage : factorial60 'number_upto_60'
$ type -a factorial60
factorial60 is a shell builtin
$ factorial60 61
factorial60: usage: Usage : factorial60 'number_upto_60'
(提醒此感谢@chepner)
方法3:重新编译的bash
只需重新编译与附加功能的bash(肮脏的方式!) - [ source code here ]。
参考文献:
enable
手册页[ here ]。bash-builtins
库(我在Ubuntu 12.04上,实际的软件包名称可能因发行版而异)来编译新的内置函数。builtin_usage
是[ defined ]。enable
内建(这里factorial60)应与在结构给出的名称的名称(注意factorial60_struct
)和_struct
应该附加到该结构中的内置名称。您还可以使用alias
,只需添加以下行~/.bashrc
将做的工作。
alias commandname='/path/to/your/binary'
您可以将其安装到您的用户路径的直接部分。通常以下选项之一:
"/bin" or "/usr/bin"
- 您需要在机器上进行root访问才能执行此操作。
或
"~/bin"
- 如果它只是为你的用户,你没有root权限。
您不能将其嵌入到bash中,但可以将其复制到路径中的某个位置,如/ usr/bin或/ usr/local/bin。然后运行它,你需要做的就是输入它的名字。 – par
您必须构建一个定制版本的bash –
您可以通过'enable'命令加载新的内置函数。这可能会涉及修改实用程序,以便它以正确的形式加载。源代码分发提供了许多[示例](http://git.savannah.gnu.org/cgit/bash.git/tree/examples/loadables?id=bash-4.3)。 – chepner