永发信息网

如何在C语言中调用shell命令

答案:3  悬赏:0  手机版
解决时间 2021-11-25 06:57
如何在C语言中调用shell命令
最佳答案
可以通过system函数,调用shell命令。
1 函数原型:
int system(const char *cmd);
2 功能:
调用cmd内容的系统命令,即shell命令。
3 头文件:
stdlib.h
4 举例:
system("ls");
打印当前工作目录下的文件。
全部回答

1、system(执行shell 命令)

相关函数 fork,execve,waitpid,popen
表头文件 #include
定义函数 int system(const char * string);
函数说明 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()会
继承环境变量,通过环境变量可能会造成系统安全的问题。

#include
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}

2、popen(建立管道I/O)

相关函数 pipe,mkfifo,pclose,fork,system,fopen
表头文件 #include
定义函数 FILE * popen( const char * command,const char * type);
函数说明 popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c
来执行参数command的指令。参数type可使用“r”代表读取,“w”
代表写入。依照此type值,popen()会建立管道连到子进程的标准输
出设备或标准输入设备,然后返回一个文件指针。随后进程便可利
用此文件指针来读取子进程的输出设备或是写入到子进程的标准输
入设备中。此外,所有使用文件指针(FILE*)操作的函数也都可以使
用,除了fclose()以外。
返回值 若成功则返回文件指针,否则返回NULL,错误原因存于errno中。
错误代码 EINVAL参数type不合法。
注意事项 在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()
会继承环境变量,通过环境变量可能会造成系统安全的问题。

#include
main()
{
FILE * fp;
char buffer[80];
fp=popen(“cat /etc/passwd”,”r”);
fgets(buffer,sizeof(buffer),fp);
printf(“%s”,buffer);
pclose(fp);
}

执行 root :x:0 0: root: /root: /bin/bash



3、使用vfork()新建子进程,然后调用exec函数族

#include
main()
{
   char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char*) };
  
   if(vfork() = =0)
   {
       execv(“/bin/ls”,argv);
   }else{        
       printf(“This is the parent process ”);
   }
}

C语言中调用shell指令,根据调用指令目的,可以区分如下两种情况:

一、需要shell指令执行某一功能,如创建文件夹,或者删除文件夹等,程序中不关注shell指令的输出,那么可以使用system函数。

system函数声明于stdlib.h, 功能为调用系统命令,形式为

int system(const char *cmd);

其中cmd为要执行的命令字符串,返回值为执行是否成功的标记。

比如在Linux下要删除当前文件夹下的所有扩展名为a的文件,即*.a, 可以写作

system("rm *.a -f");

二、不仅要执行shell命令,还需要得知运行的打印结果,并在程序中使用。

对于此,有两种方案:

1、用system命令,将输出重定向到一个txt文件中,执行后,再读取txt文件,使用后删除。

比如Linux下获取剩余内存的指令可以写作:

system("free>result.txt");//结果重定向到result.txt中。
FILE *fp = fopen("result.txt", "r");//打开文件。
int r;
while(fgetc(fp) != ' '); //忽略第一行。
fscanf(fp, "%*s%*d%*d%d",&r);//读取第四个域的值,即剩余内存值。
printf("剩余内存为%d KB ",r);//打印结果。
fclose(fp);//关闭文件。
unlink("result.txt");//删除临时文件。

2、使用重定向,需要经过磁盘读写,还要删除文件,相对低效。同时还有可能出现临时文件和已有文件重名,导致误删数据的情况。 所以一般使用更方便快捷的方式,即调用popen。

FILE *popen(const char *cmd, const char *mode);

使用popen的功能和system类似,属于方法1中执行命令和打开文件的一个组合。不过这里用到的文件是隐式的,并不会在系统中真正存在。返回的指针即结果文件指针。 当使用pclose关闭后,文件自动销毁。

方法1中的例子,用popen实现如下:

FILE *fp = popen("free", "r");//执行命令,同时创建管道文件。
int r;
while(fgetc(fp) != ' '); //忽略第一行。
fscanf(fp, "%*s%*d%*d%d",&r);//读取第四个域的值,即剩余内存值。
printf("剩余内存为%d KB ",r);//打印结果。
pclose(fp);//关闭并销毁管道文件。

三、注意事项:

虽然调用shell命令有时可以大大减少代码量,甚至有千行代码不如一句shell的说法,不过调用shell命令还是有局限性的:

1、使用shell命令会调用系统资源,效率偏低;

2、不同平台的shell指令不同,导致可移植性下降;

3、调用shell命令时会复制当前进程(fork),如果当前进程的资源占有比较大,会导致瞬间资源占用极大,甚至可能出现失败。

所以,在编码时,除非是测试性的代码,否则在正式代码中不建议使用shell。

我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
8-甲基-1-萘酚的命名不是应该按照优先次序小
新癸酸的物化性质
虚拟语句三种时态
四合永有到北京或北京西的客车吗??我2月27
德昌县属于哪个市
书斋式空谈的意思
见与不见何止想念是什么意思
做了近3年的保险客服想换工作不知何去何从?
求cry开头的英文名
丛丛美甲地址有知道的么?有点事想过去!
2015款北京现代ix35这车底盘怎么样
三明特产有什么沙县板鸭是传统名品
鸿瑞数码影楼怎么去啊,我要去那办事
孤独者 英文怎么翻译
妆点人生地址在什么地方,想过去办事,
推荐资讯
辞职后把公积金取出来 那这个账户是不是就注
广汽本田锋萢18款手动挡什么时候上市
友谊驾校(泉州石狮)地址在什么地方,我要处理
衮州到兰州开车怎么走
辣椒锅烤鱼的做法步骤图,辣椒锅烤鱼怎么做
平安派出所地址有知道的么?有点事想过去
我对男生说,我喜欢你他说,首先谢谢,我不知
“泊”字怎么组词?
香烟会逐渐退出舞台吗
小何形象设计地址在什么地方,我要处理点事!
小刘美发店地址在什么地方,我要处理点事!
喜欢、爱一个人要将就么,好想放下她,却又舍
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?