C中调用shell 脚本

c语言中调用shell脚本
本文:hi.baidu.com/lanfeng143/modify/blog/df9ff84526f5a22acffca3a0

关于在c语言中调用shell脚本,先是在百度上百度了一下
下面的这个应该是说的比较详细的
dreamerkxz.blog.163.com/blog/static/82985292200851923319849/
C程序调用shell脚本共有三种方式:system()、popen()、exec系列函数
1)system(shell命令或shell脚本路径);   
执行过程:system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。   
返回值:如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值。如果 system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。
注意:在编写具有SUID/SGID权限的程序时最好不要使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。

例:在~/myprogram/目录下有shell脚本test.sh,内容为
#!bin/bash
#test.sh
echo $HOME

在该目录下新建一个c文件systemtest.c,内容为:

#include<stdlib.h>
/*This program is used to test function system*/

main()
{
        system("~/myprogram/test.sh");
}



执行结果如下:

xiakeyou@ubuntu:~/myprogram$ gcc systemtest.c -o systemtest
xiakeyou@ubuntu:~/myprogram$ ./systemtest
/home/d/e/xiakeyou
xiakeyou@ubuntu:~/myprogram$

2)popen(char *command,char *type)   

执行过程:popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c来执行参数command的指令。参数type可使用“r”代表读取,“w”代表写入。依照此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。此外,所有使用文件指针(FILE*)操作的函数也都可以使用,除了fclose()以外。

返回值:若成功则返回文件指针,否则返回NULL,错误原因存于errno中。

注意:在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。
例:C程序popentest.c内容如下:

#include<stdio.h>
main()
{
    FILE * fp;
    charbuffer[80];
    fp=popen(“~/myprogram/test.sh”,”r”);
    fgets(buffer,sizeof(buffer),fp);
    printf(“%s”,buffer);
    pclose(fp);
}



执行结果如下:

xiakeyou@ubuntu:~/myprogram$ vim popentest.c
xiakeyou@ubuntu:~/myprogram$ gcc popentest.c -o popentest
xiakeyou@ubuntu:~/myprogram$ ./popentest
/home/d/e/xiakeyou
xiakeyou@ubuntu:~/myprogram$

只是偶能力可能有点有限,没有太看懂。直接用system()倒是脚本可是执行,只是返回值却是一塌糊涂,试了多次也没有找到什么规律。不免又看了一下上面的那篇博文,得到一些启发,可以这样来实现:
先将脚本的返回值利用 echo > XXXXX 输出到一个本地文件中
当需要这个返回值是,可是通过C语言的文件操作函数来直接从文件中读取

后来一想,这应该就是上文中POPEN的实现方法!

<think>嗯,用户问的是C语言怎么调用shell脚本。这个问题很实用,可能是想实现自动化操作或者系统管理功能。我需要回忆C语言中执行外部命令的几种方法。 最常用的应该是system()函数,它直接执行字符串形式的命令,比如system("./script.sh")。这个方法最简单但可能不够安全,特别是当命令字符串包含用户输入时会有注入风险。 接着想到exec函数族,比如execlp()。它们会替换当前进程,所以通常配合fork()使用。这种虽然复杂些但更安全可控,还能处理管道等高级功能。 用户可能是开发者或学生,想在C程序中集成脚本功能。考虑到用户要求中文回答,回复时要注意术语准确性和示例清晰度。最后必须按规则生成3-5个相关问题,问题要围绕执行方法对比、安全性、参数传递等自然延伸。 对了,还要提醒用户system()会阻塞进程,而fork-exec可以非阻塞执行。这个细节对实际应用很重要。示例代码要包含两种主流写法的基本模板,标注关键步骤。 </think>在C语言中调用Shell脚本主要通过以下几种方式实现: ### 1. 使用 `system()` 函数(最简便) ```c #include <stdlib.h> int main() { // 直接执行Shell命令或脚本 int result = system("./script.sh"); // 检查返回值(非零通常表示错误) if (result != 0) { printf("执行失败,错误码: %d\n", result); } return 0; } ``` **特点**: - 直接执行字符串形式的Shell命令 - 阻塞当前进程直到命令执行完毕 - 返回值是命令的退出状态码 ### 2. 使用 `fork()` + `exec()`(更底层控制) ```c #include <unistd.h> #include <sys/wait.h> int main() { pid_t pid = fork(); if (pid == 0) { // 子进程 execlp("/bin/sh", "sh", "-c", "./script.sh", NULL); perror("exec失败"); // 只有exec失败才会执行到这里 exit(1); } else if (pid > 0) { // 父进程 int status; waitpid(pid, &status, 0); // 等待子进程结束 if (WIFEXITED(status)) { printf("子进程退出码: %d\n", WEXITSTATUS(status)); } } else { perror("fork失败"); } return 0; } ``` **特点**: - 通过创建子进程执行脚本 - 可精细控制输入/输出流 - 避免`system()`的安全风险(如命令注入) ### 3. 使用 `popen()`(需要获取命令输出时) ```c #include <stdio.h> int main() { FILE *pipe = popen("./script.sh", "r"); // "w"表示向命令输入 if (!pipe) { perror("popen失败"); return 1; } char buffer[128]; while (fgets(buffer, sizeof(buffer), pipe) != NULL) { printf("脚本输出: %s", buffer); // 逐行读取输出 } int status = pclose(pipe); // 关闭管道并获取状态 if (status == -1) { perror("关闭失败"); } else { printf("脚本退出码: %d\n", status); } return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值