如何将命令嵌入到作为内置的bash中?
我使用C编程语言创建了一个命令行实用程序。 现在我想把这个命令嵌入bash中。 它应该充当bash内置命令’cd’。 我怎样才能做到这一点??
在bash源代码中,我看到有一个名为builtins
的目录。 我查看了该目录,发现有*.def
文件,并且有一个名为cd.def
的文件。
我认为这是bash内置cd
的定义。 现在我的问题是如何创建自己的定义???
如果你想在bash中使你的二进制文件成为内置函数
方法1:bash函数
您可以通过在~/.bashrc
文件中创建bash函数来模拟行为:
function mycommand { /path/to/your/binary #plus arguments if any } export -f mycommand
和使用mycommand
就像你使用cd
。
看看这个[tldp文章]看看它与实际内置的不同之处。
方法2:使用启用
我想我会通过创建一个用于寻找阶乘的新内置来certificate这一点。 以下是我写的代码:
/* Programme to compute the factorial of numbers up to 60 */ #include #if defined(HAVE_UNISTD_H) #include #endif #include // for shell internals #include // for struct builtin #include #include // 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(肮脏的方式!),增加function – [源代码在这里] 。
参考文献:
-
enable
联机帮助页[此处] 。 - WORD_LIST:内置函数总是被赋予指向WORD_LIST类型列表的指针。 如果内置实际上没有采用任何选项,则必须在进行任何进一步处理之前调用no_options(list)并检查其返回值。 如果返回值不为零,则函数应立即返回值EX_USAGE。 检查[this] 。
- 你需要安装
bash-builtins
库(我在Ubuntu 12.04上,实际的包名可能因发行版而不同)来编译新的内置库。 - 检查
builtin_usage
是如何定义的 。 - 要使用enable命令,系统应支持动态加载。
- 在
enable
时,内置的名称(此处为factorial60)应与结构中指定的名称匹配(注意factorial60_struct
),并且_struct
应附加到结构中的内置名称 。
您也可以使用alias
,只需在~/.bashrc
添加以下行即可完成工作。
alias commandname='/path/to/your/binary'
您可以将其直接安装到用户路径的那一部分中。 通常是以下之一:
"/bin" or "/usr/bin"
– 您需要在计算机上进行root访问才能执行此操作。
要么
"~/bin"
– 如果只是为您的用户而且您没有root访问权限。