如何将命令嵌入到作为内置的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 – [源代码在这里] 。


参考文献:

  1. enable联机帮助页[此处] 。
  2. WORD_LIST:内置函数总是被赋予指向WORD_LIST类型列表的指针。 如果内置实际上没有采用任何选项,则必须在进行任何进一步处理之前调用no_options(list)并检查其返回值。 如果返回值不为零,则函数应立即返回值EX_USAGE。 检查[this] 。
  3. 你需要安装bash-builtins库(我在Ubuntu 12.04上,实际的包名可能因发行版而不同)来编译新的内置库。
  4. 检查builtin_usage是如何定义的 。
  5. 要使用enable命令,系统应支持动态加载。
  6. enable时,内置的名称(此处为factorial60)应与结构中指定的名称匹配(注意factorial60_struct ),并且_struct应附加到结构中的内置名称

您也可以使用alias ,只需在~/.bashrc添加以下行即可完成工作。

 alias commandname='/path/to/your/binary' 

您可以将其直接安装到用户路径的那一部分中。 通常是以下之一:

"/bin" or "/usr/bin" – 您需要在计算机上进行root访问才能执行此操作。

要么

"~/bin" – 如果只是为您的用户而且您没有root访问权限。