如何在Linux中从C执行shell脚本?
答案 0 :(得分:45)
这取决于您要对脚本(或您想要运行的任何其他程序)执行的操作。
如果你只是想运行脚本system
是最简单的事情,但它也做了一些其他的事情,包括运行shell并让它运行命令(/ bin / sh大多数* nix) )。
如果您想通过其标准输入提供shell脚本或使用其标准输出,您可以使用popen
(和pclose
)来设置管道。这也使用shell(大多数* nix下的/ bin / sh)来运行命令。
这些都是图书馆功能,它们有很多功能,但如果它们不能满足您的需求(或者您只是想进行实验和学习),您也可以直接使用系统调用。这也允许你避免让shell(/ bin / sh)为你运行命令。
感兴趣的系统调用是fork
,execve
和waitpid
。您可能希望在execve
周围使用其中一个库包装器(类型man 3 exec
)以获取它们的列表。您可能还想使用其他一个等待函数(man 2 wait
将它们全部放在一起)。此外,您可能对与fork相关的系统调用clone
和vfork
感兴趣。
fork
复制当前程序,唯一的主要区别是新进程从fork调用返回0。父进程获取返回的新进程的进程ID(或错误)。
execve
用新程序替换当前程序(保持相同的进程ID)。
waitpid
来等待特定子进程完成。
将fork和execve步骤分开允许程序在创建新进程之前对其进行一些设置(不会弄乱自己)。这些包括将标准输入,输出和stderr更改为与使用的父进程不同的文件,更改进程的用户或组,关闭子进程不需要的文件,更改会话或更改环境变量。 / p>
您可能还对pipe
和dup2
系统调用感兴趣。 pipe
创建一个管道(包含输入和输出文件描述符)。 dup2
将文件描述符复制为特定文件描述符(dup
类似,但将文件描述符复制到最低可用文件描述符。)
答案 1 :(得分:25)
您可以使用system
:
system("/usr/local/bin/foo.sh");
这将在使用sh -c
执行时阻止,然后返回状态代码。
答案 2 :(得分: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;
}
答案 3 :(得分:3)
一个简单的方法是......
#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;
}
谢谢你 尤达@ http://www.unix.com/programming/216190-putting-bash-script-c-program.html
答案 4 :(得分:1)
如果您需要更精细级别的控制,您还可以使用fork
pipe
exec
路线。这将允许您的应用程序检索从shell脚本输出的数据。
答案 5 :(得分:1)
我更喜欢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);