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

前端 未结 12 1885
天命终不由人
天命终不由人 2020-11-28 05:18

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

相关标签:
12条回答
  • 2020-11-28 05:46

    There are some significant differences between exec(2) and system(3) that should be kept in mind. system() returns to the caller, whereas exec() replaces the existing code with the new image. This has been explained above.

    However, the not so subtle difference comes when you want to run a procedure and then return to your existing code, receiving the return code from the invoked procedure. system() does provide a return code, but the return code can only be used to detect an error condition, and cannot be used to recover a return code.

    One possible proper sequence of system calls is:

    #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
            }
         }
      }
    }
    

    There are other subtleties to this sequence which can be determined by a careful reading of the relevant man pages, but this code will work fine in the absence of signals, multiple child processes, etc. Also, the inline declarations may limit the scope of the variables, but are included to allow this code to be used as a template that works (you may use a different coding style :-).

    0 讨论(0)
  • 2020-11-28 05:48

    exec() replaces the current running process with the process image of the function being performed..only executable files can be invoked using this.

    system() forks off a new process implicitly to service the request and returns the value it obtained through the child process it forked initially.It uses the system's default shell to carry out the operation.

    0 讨论(0)
  • 2020-11-28 05:50

    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.

    0 讨论(0)
  • 2020-11-28 05:50

    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.

    0 讨论(0)
  • 2020-11-28 05:54

    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!

    0 讨论(0)
  • 2020-11-28 05:55

    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.

    0 讨论(0)
提交回复
热议问题