Difference between “system” and “exec” in Linux?

2020-01-26 04:35发布

What is the difference between system and exec family commands? Especially I want to know which one of them creates child process to work?

标签: c linux exec fork
12条回答
叼着烟拽天下
2楼-- · 2020-01-26 04:55

System() will create child process and invoke another sub shell while exec() will not create child process.Given Example will clear difference.

some code...

exec('ls -l')

echo "1 2 3" // This will not executed in bash (as exec command use same shell)

some code ...

system (ls -l) echo "1 2 3" // This will be executed after finishing System child process as they are different from parent PID.

查看更多
家丑人穷心不美
3楼-- · 2020-01-26 04:56

system() will invoke your systems default command shell, which will execute the command string passed as an argument, that itself may or may not create further processes, that would depend on the command and the system. Either way, at least a command shell process will be created.

With system() you can invoke any command, whereas with exec(), you can only invoke an executable file. Shell scripts and batch files must be executed by the command shell.

Basically they are entirely different used for different purposes. Moreover exec() replaces the calling process, and does not return. A more useful comparison would be between system() and spawn(). While system may be simpler to invoke, it returns a value that tells you whether the command shell was invoked, and tells you nothing about the success of the command itself. With spawn() you can get the process's exit code; by convention non-zero is used to indicate error conditions. Like exec() spawn() must invoke an executable, not a shell script or built-in command.

查看更多
在下西门庆
4楼-- · 2020-01-26 04:57

In general, "system" is so inefficient and you should not use it unless you have a small code. If you need to execute several programs in your process, you would better use fork&exec though you make it more complicated. Here is a list of differences between them:

1- "system" command creates a copy of shell to execute your program. Every time you call a system, you create a copy of shell. So do not use it when you have lots of programs to execute inside your process.

2- Specifically, if you want to execute system functions such as "mv", "mkdir", it would be better to use routines such as mkdir(), unlink() or remove() instead of executing them through "system("rm ....") or system("mkdir ....")".

3- Since system calls shell to execute your desired program, you may have some user permission problems. For example, someone may crack your code and execute something else instead of the program you intended to execute through system command.

For more information, you may read chapter 11 of this book: "UNIX Systems Programming" by David Curry.

查看更多
相关推荐>>
5楼-- · 2020-01-26 05:00

system() will execute the supplied command in a child process that it spawns. exec() will replace the current process with the invocation of the new executable that you specify. If you want to spawn a child process using exec, you'll have to fork() your process beforehand.

查看更多
爷的心禁止访问
6楼-- · 2020-01-26 05:04

The exec function replace the currently running process image when successful, no child is created (unless you do that yourself previously with fork()). The system() function does fork a child process and returns when the command supplied is finished executing or an error occurs.

查看更多
再贱就再见
7楼-- · 2020-01-26 05:04

JonSpencer answer is fine, except that child_status must be an int (no a pointer to int) and has to be passed to wait function by reference.

So, the code would be mainly the same, just changing those couple of things:

#include <unistd.h>
#include <sys/wait.h>
#define NUMARGS 2

int main (int argc, char *argv[])
{
  pid_t child_pid, wait_pid;
  int child_status;
  char * exec_path = "/path/to/executable";
  char * child_args[NUMARGS] = {0,0};

  child_pid = fork();
  if (0 == child_pid)
  { // In child process
     ...
     int child_ret_code = execv(exec_path, child_args);  //or whichever flavor of exec() that floats your boat
     ... // if child_ret_code = -1, process execv() error return
  }
  else if (-1 == child_pid)
  {
     ... //process error return from fork
  }
  else if (0 < child_pid)
  {  // Parent process
     wait_pid = wait(&child_status);
     if (-1 == wait_pid)
     {
       ... //Process error return from wait()
     }
     else
     {  //  Good fork/exec/wait
        if (WIFEXITED(child_status))  // Child exited normally and hopefully returned exit code
        {
           int child_ret_code = WEXITSTATUS(child_status);
           ...  // Continue on as you would after call to system(3)
                //   except now you have the return code you needed
        }
     }
  }
}

(Point out that I don't have enough reputation yet to comment Jon's post so I edited it. Some people rejected the edition asking me to answer the question instead of editing it, but I think that in this case it is much simpler, practical and clear to edit an existing code just correcting a small mistake than to write a full copy/paste/modify answer.) Anyway, thanks JonSpencer for your answer, it was really useful for me!

查看更多
登录 后发表回答