linux下如何用c语言调用shell命令-转
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命令-转相关推荐
- c语言调用shell命令一 popen使用以及获取命令返回值
产品升级,新增网卡,原先的产品是arm平台,新网卡是mips平台,需要开发网卡的配置程序,该程序原计划是以守护进程的形式后台执行,不过测试过程中发现系统不是特别稳定,导致程序时不时奔溃下,一时半会儿无 ...
- Linux下查看CPU/内存/硬盘的shell命令
1.cpu查看 1)cpu个数:#cat /proc/cpuinfo | grep "physical id" | uniq | wc -l 2)cpu核数:#cat /proc/ ...
- linux脚本查看系统内存,二个linux下查看内存使用情况的shell脚本()
摘要 腾兴网为您分享:二个linux下查看内存使用情况的shell脚本(),政务易,悦作业,优化大师,王者荣耀等软件知识,以及单向历app,优路教育app,kimoji,开关电源设计软件,皮皮高清影视 ...
- java操作Linux 调用shell命令,shell脚本
1.问题 在最近做的项目当中,需要用Java调用基于python写的两个不同的模型运行并且得到实验结果: 1.在服务器上运行的文本识别模型 2.在本地Ubuntu中annacoda 虚拟环境中运行的影 ...
- 从Ruby调用Shell命令
如何从Ruby程序内部调用Shell命令? 然后如何将这些命令的输出返回到Ruby? #1楼 上面的答案已经很不错了,但是我真的很想分享以下摘要文章:" 在Ruby中运行Shell命令的6种 ...
- Linux下ps查找进程用kill终止命令
Linux下ps查找进程用kill终止命令<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:offic ...
- python调用shell命令-用Python调用Shell命令
Python经常被称作"胶水语言",因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库,也当然可以用Python调用Shell命令. 用Python调用Shell命令有如 ...
- python调用shell命令-在Python中执行shell命令的6种方法,你都知道吗?
原标题:在Python中执行shell命令的6种方法,你都知道吗? Python经常被称作"胶水语言",因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库.今天我们就讲解 ...
- python 执行shell_用Python调用Shell命令
Python经常被称作"胶水语言",因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库,也当然可以用Python调用Shell命令. 用Python调用Shell命令有如 ...
最新文章
- Setting up Jupyter with Python 3 on Ubuntu
- boost::signals2模块thread_safe_signals 库替代线程模型的基本测试
- 重磅发布 | 承载亿级流量的开发框架,闲鱼Flutter技术解析与实战大公开
- vue获取div中的值_一篇文章看懂Vue.js的11种传值通信方式
- 编程体系结构(07):JavaEE之Web开发
- python requests cookiejar,Python requests模块cookie实例解析
- 小米变了?红米Note7今日开售 坚持了9分36秒...
- python从入门到精通需要多久-Python从入门到精通
- mysql中char存储中文_数据库中的字符类型存储字符和汉字的数量
- curl 命令-接口测试
- 罗永浩是偏执,还是骗子?
- java csv转owl_数据处理第2节:将列转换为正确的形状
- ssm基于微信小程序的恋上诗词设计与实现毕业设计源码011431
- 水利水电课程指导之建筑制图基础_第三章
- [弱校联萌2016]2016弱校联盟十一专场10.3
- 圆满收官,百花齐放!2022企业级低代码应用大赛获奖结果公布
- JS判断安卓端或者苹果端并下载
- 小程序生成图片保存到系统相册
- #中英对照#伺服与步进电机的开闭环控制逻辑与低频矩频特性
- linux虚机备份成iso,虚拟机vdi转换成可安装iso的变通解决方案