C语言中执行shell命令
来源:互联网 发布:mac os sierra百度云 编辑:程序博客网 时间:2024/05/17 23:11
1、system系统调用
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()会继承环境变量,通过环境变量可能会造成系统安全的问题。
eg:
#include<stdlib.h> int main() { system("clear"); return 1; }
2、popen(建立管道I/O)
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c command来执行参数command的指令。依照此type(r,w)值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。此外,所有使用文件指针(FILE*)操作的函数也都可以使用,除了fclose()以外。
返回值,若成功则返回文件指针,否则返回NULL,错误原因存于errno中。
在编写具SUID/SGID权限的程序时请尽量避免使用popen(),popen()会继承环境变量,通过环境变量可能会造成系统安全的问题。
#include<stdio.h> int main() { FILE *fp; char buffer[80]; fp=popen("cat /etc/passwd","r"); fgets(buffer,sizeof(buffer),fp); printf("%s",buffer); pclose(fp); return 0; }
3、exec函数族
exec函数
调用一种exec函数时,该进程完全由新程序代换,而新程序则从其main函数开始执行。
因为调用exec并不创建新进程,所以前后的进程I D并未改变。
exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。
进程ID没有改变。执行新程序的进程还保持了原进程的下列特征:
.进程ID和父进程ID。
.实际用户ID和实际组ID。
.添加组ID。
.进程组ID。
.会话ID。
.控制终端。
.闹钟尚余留的时间。
.当前工作目录。
.根目录。
.文件方式创建屏蔽字。
.文件锁。
.进程信号屏蔽。
.未决信号。
.资源限制。
.tms_utime, tms_stime, tms_cutime以及t m s u s t i m e值。
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execve(const char *filename, char *const argv[],char *const envp[]);
3.1、execv
使用vfork()新建子进程,然后调用execv
eg:
#include "unistd.h" #include "stdio.h" int main() { char *argv[] = {"ls", "-al", "/etc/passwd", "char*"}; if(vfork() == 0) { execv("/bin/ls", argv); } else { printf("parent.\n") } return 0;}
3.2、execl
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include <sys/wait.h>int main(void){pid_t pid;char *ttargv[]={"tt","123456",NULL};char *lsargv[]={"ls","-lh","/home",NULL};pid=fork();if(pid==-1) return 1;else if(pid==0) //child{ printf("child process start:%d\n",getpid());#if 0 //execl("./tt","tt","123456",NULL);//执行外部程序 execl("/bin/ls","ls","-l","-h","/home",NULL);#else //execv("./tt",ttargv); execv("/bin/ls",lsargv);#endif //perror("execl");exit(2);}printf("parent wait child\n");int val;wait(&val);printf("return code:%d\n",WEXITSTATUS(val));return 0;}
3.3、execle
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include <sys/wait.h>int main(void){pid_t pid;char *ttargv[]={"tt","123456",NULL};char *myenv[]={"PATH=./:/tmp:/usr/bin","NAME=king","USER=OOOO",NULL};pid=fork();if(pid==-1) return 1;else if(pid==0) //child{ printf("child process start:%d\n",getpid());#if 0 #if 0 execl("./tt","tt","123456",NULL);//执行外部程序 #else execle("./tt","tt","45678",NULL,myenv); #endif //#else execve("./tt",ttargv,myenv);#endif //perror("execl");exit(2);}printf("parent wait child\n");int val;wait(&val);printf("return code:%d\n",WEXITSTATUS(val));return 0;}
3.4、execlp
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include <sys/wait.h>int main(void){pid_t pid;char *ttargv[]={"tt","123456",NULL};char *lsargv[]={"ls","-lh","/home",NULL};pid=fork();if(pid==-1) return 1;else if(pid==0) //child{ printf("child process start:%d\n",getpid());#if 1 #if 0 //execl("./tt","tt","123456",NULL);//执行外部程序 //execl("/bin/ls","ls","-l","-h","/home",NULL); #else //如果没给路径时根据环境PATH找可执行程序 //execlp("tt","tt","123456",NULL);//执行外部程序 execlp("ls","ls","-l","-h","/home",NULL); #endif //#else //execv("./tt",ttargv); execv("/bin/ls",lsargv);#endif //perror("execl");exit(2);}printf("parent wait child\n");int val;wait(&val);printf("return code:%d\n",WEXITSTATUS(val));return 0;}
4、总结
a、system()和exec()都可以执行进程外的命令,system是在原进程上开辟了一个新的进程,但是exec是用新进程(命令)覆盖了原有的进程
b、system()和exec()都有能产生返回值,system的返回值并不影响原有进程,但是exec的返回值影响了原进程
1 0
- 在c语言中执行shell命令
- C语言中执行shell命令
- c语言执行shell命令
- c语言执行shell命令
- C语言执行shell命令
- linux c语言实现 执行shell命令
- C语言模拟终端执行shell命令
- c函数中执行shell 命令
- 让你提前认识软件开发(23):如何在C语言中执行shell命令?
- C语言popen创建管道文件循环执行shell命令
- linux C 语言的 system(执行shell 命令)
- linux C 语言的 system(执行shell 命令)
- 在C语言中执行shell命令 http://www.cnblogs.com/mydomain/archive/2013/04/20/3033076.html
- C语言程序中调用shell去执行代码
- vi中执行shell命令
- vi中执行shell命令
- vim 中执行shell命令
- vi中执行shell命令
- 使用Gulp
- IAR查找文件提示Failed to read
- 第四次C++ 作业
- NYOJ_711_最舒适的路线【并查集】
- sqlServer+hibernatea+ maven配置
- C语言中执行shell命令
- html表格
- JavaのNIO
- PAT 1022 乙等 (D进制的A+B) C++版
- 二叉树的后序遍历
- 记京东Java开发实习生二面
- 关于“批量将手动输入的中括号数字变成上标”实践中的问题
- 进程间通信
- 数据库课程设计