如何在Linux中从C执行shell脚本?

Jan*_*ard 49 c linux shell

如何在Linux中从C执行shell脚本?

nat*_*ose 48

这取决于您要对脚本(或您要运行的任何其他程序)执行的操作.

如果你只是想运行脚本system是最简单的事情,但它也做了一些其他的事情,包括运行shell并让它运行命令(/ bin/sh在大多数*nix下).

如果要通过其标准输入提供shell脚本或使用其标准输出,可以使用popen(和pclose)来设置管道.这也使用shell(大多数*nix下的/ bin/sh)来运行命令.

这些都是图书馆功能,它们有很多功能,但如果它们不能满足您的需求(或者您只是想进行实验和学习),您也可以直接使用系统调用.这也允许你避免让shell(/ bin/sh)为你运行命令.

感兴趣的系统调用fork,execvewaitpid.您可能希望使用其中一个库包装器execve(键入man 3 exec它们的列表).您可能还想使用其他一个等待函数(man 2 wait全部都有).此外,您可能对系统调用感兴趣,clone并且vfork与fork相关.

fork复制当前程序,唯一的主要区别是新进程从fork调用返回0.父进程获取返回的新进程的进程ID(或错误).

execve 用新程序替换当前程序(保持相同的进程ID).

waitpid 父进程使用它来等待特定的子进程完成.

将fork和execve步骤分开允许程序在创建新进程之前对其进行一些设置(不会弄乱自己).这些包括将标准输入,输出和stderr更改为与使用的父进程不同的文件,更改进程的用户或组,关闭子进程不需要的文件,更改会话或更改环境变量.

您还可能有兴趣在pipedup2系统调用. pipe创建一个管道(包含输入和输出文件描述符). dup2将文件描述符复制为特定文件描述符(dup类似但将文件描述符复制到最低可用文件描述符).

  • 值得注意的是fork()非常便宜,因为内存是写时复制的,并且一旦程序分叉就不会重复. (2认同)
  • @Tom Anderson:如果shell脚本具有为有效用户设置的执行权限,并且有一个适当的shabang第一行列出了有效用户也有权执行的文件,并且本身也不是某种类型的脚本,那么内核将调用使用脚本文件在shabang行上列出的文件.如果脚本的shabang是`#!/ bin/csh`那么`/ bin/sh`将不会在fork/exec场景中运行.如果它是`#!/ bin/sh`那么它将在fork/exec场景中,但是对于这个脚本,`system` version`/bin/sh`会运行两次. (2认同)

Mat*_*hen 25

你可以使用system:

system("/usr/local/bin/foo.sh");
Run Code Online (Sandbox Code Playgroud)

这将在使用时执行阻止sh -c,然后返回状态代码.

  • +1不要忘记包含`<stdlib.h>`(http://linux.die.net/man/3/system) (3认同)
  • ...假设它有可执行位和shebang线.一般来说,`system("/ bin/sh /usr/local/bin/foo.sh");`.是的,这实际上是两次调用shell. (2认同)

pmg*_*pmg 16

如果你对POSIX没问题,你也可以使用popen()/pclose()

#include <stdio.h>
#include <stdlib.h>

int main(void) {
/* ls -al | grep '^d' */
  FILE *pp;
  pp = popen("ls -al", "r");
  if (pp != NULL) {
    while (1) {
      char *line;
      char buf[1000];
      line = fgets(buf, sizeof buf, pp);
      if (line == NULL) break;
      if (line[0] == 'd') printf("%s", line); /* line includes '\n' */
    }
    pclose(pp);
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)