c-如何在bash中嵌入一个内置的命令

  • 本文关键字:一个 内置 命令 bash c 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

使用CCD_ 6就像使用cd一样

请看一下这篇[tldp文章],了解它与实际内置的不同之处。

方法2:使用enable

我想我可以通过创建一个新的内建函数来证明这一点。下面是我写的代码:

/* 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("%llun",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复制到本地库位置,例如/usr/local/lib/mylib/

通过在~/.bashrc(或者/etc/bash.bashc,如果你希望其他用户使用新的内置)中添加以下内容,启用(持久)新的内置

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(肮脏的方式!)并添加功能-[此处为源代码]。


参考文献:

  1. enable手册页[此处]
  2. WORD_LIST:总是为内置函数提供一个指向类型为WORD_LIST的列表的指针。如果内置实际上不接受任何选项,则必须调用no_options(list)并在进行任何进一步处理之前检查其返回值。如果返回值为非零,则函数应立即返回值EX_USAGE。检查[这个]
  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访问权限。

相关内容

  • 没有找到相关文章