繁体   English   中英

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

[英]How to execute a shell script from C in Linux?

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

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

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

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

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

感兴趣的系统调用是forkexecvewaitpid 您可能想要在execve周围使用一个库包装器(键入man 3 exec以获取它们的列表)。 您可能还想使用其他一个等待函数( man 2 wait它们全部)。 另外,您可能对与vfork相关的系统调用clonevfork感兴趣。

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

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

父进程使用waitpid来等待特定子进程完成。

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

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

你可以使用system

system("/usr/local/bin/foo.sh");

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

如果你对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;
}

一个简单的方法是......

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


#define SHELLSCRIPT "\
#/bin/bash \n\
echo \"hello\" \n\
echo \"how are you\" \n\
echo \"today\" \n\
"
/*Also you can write using char array without using MACRO*/
/*You can do split it with many strings finally concatenate 
  and send to the system(concatenated_string); */

int main()
{
    puts("Will execute sh with the following script :");
    puts(SHELLSCRIPT);
    puts("Starting now:");
    system(SHELLSCRIPT);    //it will run the script inside the c code. 
    return 0;
}

说谢谢
Yoda @ http://www.unix.com/programming/216190-putting-bash-script-c-program.html

我更喜欢fork + execlp用于“更精细级别”的控制,正如doron所提到的那样。 示例代码如下所示。

将命令存储在char数组参数中,并将malloc空间存储为结果。

int fd[2];
pipe(fd);
if ( (childpid = fork() ) == -1){
   fprintf(stderr, "FORK failed");
   return 1;
} else if( childpid == 0) {
   close(1);
   dup2(fd[1], 1);
   close(fd[0]);
   execlp("/bin/sh","/bin/sh","-c",parameters,NULL);
}
wait(NULL);
read(fd[0], result, RESULT_SIZE);
printf("%s\n",result);

如果你需要更精细级别的控制,你也可以去fork pipe exec路线。 这将允许您的应用程序检索从shell脚本输出的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM