由执行的命令
system()
以后通常不会继续
系统()
返回。
系统()
启动新进程(使用
fork() + exec*()
或
CreateProcess()
等),然后等待该过程完成后再返回。但是,如果命令生成了孤儿,那么他们可以继续生活。
这可能会有影响,取决于
SHELL
被使用
系统()
:
std::system("nohup tar xvzf /path/to/some/file.tar.gz &");
自从
系统()
使用shell启动命令(可能
/bin/sh
)它反过来使用流程的当前环境(最显著的是
PATH
以及可能用来影响命令所使用的共享库的变量——也可以通过重定向发送命令字符串,将命令置于后台(如上图所示)等——这通常被视为安全风险。最小化风险的一种方法是创建自己的系统函数,而不使用shell或环境。例子:
#include <iostream>
#include <array>
#include <type_traits> // std::common_type_t
#include <cstdlib> // std::exit
#include <utility> // std::forward
// fork, exec, waitpid
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
template<typename... Ts>
int mysystem(Ts&&... ts) {
int wstatus=-1;
pid_t pid = fork();
if(pid==0) { // in child process
std::array<std::common_type_t<Ts...>, sizeof...(ts) + 1> cmd{ std::forward<Ts>(ts)... };
execv(cmd[0], const_cast<char* const*>( cmd.data() ));
std::exit(1); // we'll only get here if execv failed starting the command
} else if(pid!=-1) { // in parent process
// wait for the child to terminate
// the exit status from the child will be returned in wstatus
waitpid(pid, &wstatus, 0); // 0 = wait forever
} // else { /* fork() failed */ }
return wstatus;
}
int main() {
//int ws = mysystem("/usr/bin/find", ".");
//int ws = mysystem("/usr/bin/bash", "-i");
int ws = mysystem("/usr/bin/tar", "xvzf", "/path/to/some/file.tar.gz");
std::cout << "--------------------\n"
"Exit status: " << WEXITSTATUS(ws) << "\n"
"Termination signal: " << WTERMSIG(ws) << "\n"
"Core dumped: " << std::boolalpha << WCOREDUMP(ws) << "\n";
}