Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在bash中嵌入一个内置的命令?_C_Bash - Fatal编程技术网

C 如何在bash中嵌入一个内置的命令?

C 如何在bash中嵌入一个内置的命令?,c,bash,C,Bash,我使用C编程语言创建了一个命令行实用程序。现在我想将该命令嵌入bash。它应该充当bash内置命令“cd”。 我该怎么做 在bash源代码中,我看到了一个名为builtins的目录。我查看了那个目录,发现有*.def文件,还有一个名为cd.def的文件 我认为这就是bash内置的cd的定义。现在我的问题是如何创建我自己的定义???如果您希望使二进制文件成为内置bash 方法1:bash函数 您可以通过在文件中创建bash函数来模拟行为,例如~/.bashrc: function mycomman

我使用C编程语言创建了一个命令行实用程序。现在我想将该命令嵌入bash。它应该充当bash内置命令“cd”。 我该怎么做

在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
一样

一定要看看这与实际内置的有什么不同

方法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*
};
将共享对象factorial.so复制到本地库位置,例如
/usr/local/lib/mylib/

通过在~/.bashrc(或/etc/bash.bashrc,如果您希望其他用户使用新的内置代码,则可以在~/.bashrc)中添加以下内容来启用(持久化)新的内置代码

瞧!您已经准备好在新的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(肮脏的方式!),并添加功能-


参考文献:

  • 启用
    手册页
  • WORD_LIST:内置函数始终被赋予指向WORD_LIST类型列表的指针。如果内置函数实际上不接受任何选项,则必须调用no_options(list)并检查其返回值,然后才能进行进一步处理。如果返回值不为零,则函数应立即返回值EX_USAGE。检查
  • 您需要安装
    bash内置程序
    library(我在Ubuntu 12.04上,实际的包名可能因发行版而异)来编译新的内置程序
  • 检查
    内置用法的使用情况
  • 要使用enable命令,系统应支持动态加载
  • enable
    中,内置名(此处为factorial60)应与结构中给出的名称匹配(注意
    factorial60\u struct
    ),并且
    \u struct
    应附加到结构中的内置名后


  • 您也可以使用
    别名
    ,只需在
    ~/”中添加下面的一行即可。bashrc
    将完成这项工作

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

    您可以直接将其安装到用户路径的该部分。通常为下列情况之一:

    “/bin”或“/usr/bin”
    -您需要在计算机上具有root访问权限才能执行此操作


    “~/bin”
    -如果它只针对您的用户,而您没有root访问权限。

    您不能将它嵌入bash,但可以将它复制到路径中的某个位置,如/usr/bin或/usr/local/bin。然后要运行它,您只需键入它的名称。您必须构建一个自定义版本的Bash,您可以通过
    enable
    命令加载新的内置项。不过,这可能涉及修改实用程序,使其以正确的形式加载。源代码发行版提供了许多功能。
    cd
    不是二进制文件。若是,它不会更改其子进程的工作目录,那个么您可以使用bashfunction@EdHeal:已更新:-)
    cd
    内置不是出于性能原因。
    $ 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'
    
    alias commandname='/path/to/your/binary'