C程序调用shell脚本共有三种法子 :system()、popen()、exec系列函数 system()不用你自己去产生进程,它已经封装了,直接加入自己的命令exec 需要你自己 fork 进程,然后exec 自己的命令。

popen() 也可以实现执行你的命令,比system 开销小

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来确认履行 成功 。

system命令以其简略 高效的作用得到很很广泛 的利用 ,下面是一个例子

例:在~/test/目录下有shell脚本test.sh,内容为

#!bin/bash

#test.sh

echo hello

在同层目录下新建一个c文件system_test.c,内容为:

#include<stdlib.h>

int main()

{

system("~/test/test.sh");//system可以调用脚本也可以直接调用linux命令,和shell输入基本一致。

}

履行 效果 如下:

[root@localhost test]$gcc system_test.c -o system_test

[root@localhost test]$./system_test

hello

[root@localhost test]$

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);//此时的buffer内容已经重新生成适合管道操作的数据

pclose(fp);

}

履行 效果 如下:

[root@localhost test]$ vim popentest.c

[root@localhost test]$ gcc popentest.c -o popentest

[root@localhost test]$ ./popentest

/root/test

[root@localhost test]$

3.exec

exec函数族包括6个函数:

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, const char *envp[]);
int execv(const char *path, const char *argv[]);
int execve(const char *path, const char *argv[], const char *envp[];
int execvp(const char *file, const char *argv[]);

参数说明:

execl的第一个参数是包括路径的可执行文件,后面是列表参数,列表的第一个为命令path,接着为参数列表,最后必须以NULL结束。
execlp的第一个参数可以使用相对路径或者绝对路径。
execle,最后包括指向一个自定义环境变量列表的指针,此列表必须以NULL结束。
execv,v表示path后面接收的是一个向量,即指向一个参数列表的指针,注意这个列表的最后一项必须为NULL。
execve,path后面接收一个参数列表向量,并可以指定一个环境变量列表向量。
execvp,第一个参数可以使用相对路径或者绝对路径,v表示后面接收一个参数列表向量。

exec被调用时会替换调用它的进程的代码段和数据段(但是文件描述符不变),直接返回到调用它的进程的父进程,如果出错,返回-1并设置errno。

例子:
#include <unistd.h>
int main(int argc, char *argv[])
{
        char *envp[]={"PATH=/tmp", "USER=lei", "STATUS=testing", NULL};
        char *argv_execv[]={"echo", "excuted by execv", NULL};
        char *argv_execvp[]={"echo", "executed by execvp", NULL};
        char *argv_execve[]={"env", NULL};
        if(fork()==0) {
                if(execl("/bin/echo", "echo", "executed by execl", NULL)<0)
                        perror("Err on execl");
        }
        if(fork()==0) {
                if(execlp("echo", "echo", "executed by execlp", NULL)<0)
                        perror("Err on execlp");
        }
        if(fork()==0) {
                if(execle("/usr/bin/env", "env", NULL, envp)<0)
                        perror("Err on execle");
        }
        if(fork()==0) {
                if(execv("/bin/echo", argv_execv)<0)
                        perror("Err on execv");
        }
        if(fork()==0) {
                if(execvp("echo", argv_execvp)<0)
                        perror("Err on execvp");
        }
        if(fork()==0) {
                if(execve("/usr/bin/env", argv_execve, envp)<0)
                        perror("Err on execve");
        }
}

程序里调用了2 个Linux 常用的系统命令,echo和env。echo会把后面跟的命令行参数原封不动的打印出来,env用来列出所有环境变量。
    由于各个子进程执行的顺序无法控制,所以有可能出现一个比较混乱的输出--各子进程打印的结果交杂在一起,而不是严格按照程序中列出的次序。
最常见的错误:
    平时的编程中,如果用到了exec 函数族,一定记得要加错误判断语句。因为与其他系统调用比起来,exec很容易受伤,被执行文件的位置,权限等很多因素都能导致该调用的失败。
    最常见的错误是:
    1)找不到文件或路径,此时errno 被设置为ENOENT;
    2)数组argv和envp忘记用NULL结束,此时errno被设置为EFAULT;
    3)没有对要执行文件的运行权限,此时errno被设置为EACCES。

linux下如何用c语言调用shell命令-转相关推荐

  1. c语言调用shell命令一 popen使用以及获取命令返回值

    产品升级,新增网卡,原先的产品是arm平台,新网卡是mips平台,需要开发网卡的配置程序,该程序原计划是以守护进程的形式后台执行,不过测试过程中发现系统不是特别稳定,导致程序时不时奔溃下,一时半会儿无 ...

  2. Linux下查看CPU/内存/硬盘的shell命令

    1.cpu查看 1)cpu个数:#cat /proc/cpuinfo | grep "physical id" | uniq | wc -l 2)cpu核数:#cat /proc/ ...

  3. linux脚本查看系统内存,二个linux下查看内存使用情况的shell脚本()

    摘要 腾兴网为您分享:二个linux下查看内存使用情况的shell脚本(),政务易,悦作业,优化大师,王者荣耀等软件知识,以及单向历app,优路教育app,kimoji,开关电源设计软件,皮皮高清影视 ...

  4. java操作Linux 调用shell命令,shell脚本

    1.问题 在最近做的项目当中,需要用Java调用基于python写的两个不同的模型运行并且得到实验结果: 1.在服务器上运行的文本识别模型 2.在本地Ubuntu中annacoda 虚拟环境中运行的影 ...

  5. 从Ruby调用Shell命令

    如何从Ruby程序内部调用Shell命令? 然后如何将这些命令的输出返回到Ruby? #1楼 上面的答案已经很不错了,但是我真的很想分享以下摘要文章:" 在Ruby中运行Shell命令的6种 ...

  6. Linux下ps查找进程用kill终止命令

    Linux下ps查找进程用kill终止命令<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:offic ...

  7. python调用shell命令-用Python调用Shell命令

    Python经常被称作"胶水语言",因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库,也当然可以用Python调用Shell命令. 用Python调用Shell命令有如 ...

  8. python调用shell命令-在Python中执行shell命令的6种方法,你都知道吗?

    原标题:在Python中执行shell命令的6种方法,你都知道吗? Python经常被称作"胶水语言",因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库.今天我们就讲解 ...

  9. python 执行shell_用Python调用Shell命令

    Python经常被称作"胶水语言",因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库,也当然可以用Python调用Shell命令. 用Python调用Shell命令有如 ...

最新文章

  1. Setting up Jupyter with Python 3 on Ubuntu
  2. boost::signals2模块thread_safe_signals 库替代线程模型的基本测试
  3. 重磅发布 | 承载亿级流量的开发框架,闲鱼Flutter技术解析与实战大公开
  4. vue获取div中的值_一篇文章看懂Vue.js的11种传值通信方式
  5. 编程体系结构(07):JavaEE之Web开发
  6. python requests cookiejar,Python requests模块cookie实例解析
  7. 小米变了?红米Note7今日开售 坚持了9分36秒...
  8. python从入门到精通需要多久-Python从入门到精通
  9. mysql中char存储中文_数据库中的字符类型存储字符和汉字的数量
  10. curl 命令-接口测试
  11. 罗永浩是偏执,还是骗子?
  12. java csv转owl_数据处理第2节:将列转换为正确的形状
  13. ssm基于微信小程序的恋上诗词设计与实现毕业设计源码011431
  14. 水利水电课程指导之建筑制图基础_第三章
  15. [弱校联萌2016]2016弱校联盟十一专场10.3
  16. 圆满收官,百花齐放!2022企业级低代码应用大赛获奖结果公布
  17. JS判断安卓端或者苹果端并下载
  18. 小程序生成图片保存到系统相册
  19. #中英对照#伺服与步进电机的开闭环控制逻辑与低频矩频特性
  20. linux虚机备份成iso,虚拟机vdi转换成可安装iso的变通解决方案

热门文章

  1. ansys workbench 帮助文档在哪_中英对照读ANSYS帮助文档,是怎么玩的?
  2. jpype,jpython调用jar包中jdk的问题.
  3. Java中函数参数不固定的问题
  4. hibernate优化
  5. debug模式不报错,release模式报错
  6. RHEL6基础之十二RHEL用户和组基础
  7. Memcached的几种Java客户端(待实践)
  8. 19. yum 常用命令《Mr.Robot》
  9. Python核心编程答案(自整理)
  10. ZOJ 1013 Great Equipment(DP)