linux管理员权限下执行popen,执行shell命令的函数——system()、popen()

1、FILE* popen(const char* cmd,const char* type);

int pclose(FILE* stream);

popen()函数fork()一个子进程,创建管道用于父子进程间通信,父进程要么从管道读,要么往管道写,执行一个shell以运行命令来开启一个进程

相比于system()的又是在于使用简单,popen()只返回两个值,成功返回子进程的status,失败返回-1

2、int system(const char* cmd);

处理了fork()、execl()、waitpid()这些细节,还有一些信号

1、这个库函数使用fork()创建一个子进程来;

2、子进程调用/bin/sh-c cmd执行指定的参数命令(/bin/sh一般是一个软连接,指向某个具体的shell,比如bash,-c选项告诉shell从字符串cmd中读取命令),执行完之后返回调用原进程;

3、父进程调用waitpid等待子进程结束。

执行命令时SIGCHLD将被阻塞,在调用system()的进程中SIGINT和SIGQUIT将被忽略。

返回值:

如果cmd是NULL,返回非0,一般为1;

如果fork()失败,即子进程无法被创建,返回-1;

如果shell在子进程中不能被替换,即execl()失败,返回127;

如果所有系统调用成功了,子进程执行cmd命令,但cmd命令不一定执行成功,返回cmd通过exit或return返回的值;

system()源码:int system(const char * cmdstring)

{

pid_t pid;

int status;

if(cmdstring == NULL)

{

return (1); //如果cmdstring为空,返回非零值,一般为1

}

if((pid = fork())<0)

{

status = -1; //fork失败,返回-1

}

else if(pid == 0)

{

execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);

_exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在啦~~

}

else //父进程

{

while(waitpid(pid, &status, 0) 

{

if(errno != EINTR)

{

status = -1; //如果waitpid被信号中断,则返回-1

break;

}

}

}

return status; //如果waitpid成功,则返回子进程的返回状态

}

system()会继承环境变量,编写具有SUID/SGID权限的程序时不要用这个函数

建议system()只用来执行shell命令

建议监控一下system()函数执行完毕之后的errno值

建议使用popen()代替system()

《完》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值