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 05:05

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.

查看更多
Viruses.
3楼-- · 2020-01-26 05:08

int system(const char *cmdstring);

Ex: system("date > file");


In general, system is implemented by calling fork, exec, and waitpid, there are three types of return values.

  • If either the fork fails or waitpid returns an error other than EINTR, system returns –1 with errno set to indicate the error.
  • If the exec fails, implying that the shell can't be executed, the return value is as if the shell had executed exit(127).
  • Otherwise, all three functions—fork, exec, and waitpid—succeed, and the return value from system is the termination status of the shell, in the format specified for waitpid.

The fork function is to create a new process (the child) that then causes another program to be executed by calling one of the exec functions. When a process calls one of the exec functions, that process is completely replaced by the new program, and the new program starts executing at its main function. The process ID does not change across an exec, because a new process is not created; exec merely replaces the current process—its text, data, heap, and stack segments—with a brand new program from disk.

There are six different exec functions,


int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );

int execv(const char *pathname, char *const argv []);

int execle(const char *pathname, const char *arg0, .../* (char *)0, char *const envp[] */ );

int execve(const char *pathname, char *const argv[], char *const envp []);

int execlp(const char *filename, const char *arg0,... /* (char *)0 */ );

int execvp(const char *filename, char *const argv []);

查看更多
Lonely孤独者°
4楼-- · 2020-01-26 05:09

system() calls out to sh to handle your command line, so you can get wildcard expansion, etc. exec() and its friends replace the current process image with a new process image.

With system(), your program continues running and you get back some status about the external command you called. With exec(), your process is obliterated.

In general, I guess you could think of system() as a higher-level interface. You could duplicate its functionality yourself using some combination fork(), exec(), and wait().

To answer your final question, system() causes a child process to be created, and the exec() family do not. You would need to use fork() for that.

查看更多
迷人小祖宗
5楼-- · 2020-01-26 05:10

system() invokes the desired program or built-in command using a shell, this is an inefficient way because a shell is started before the program is started.

In the case of the exec family of system calls, a whole new image is being created, that is, they replace the current process with a new process specified by the path or file or whatever argument you are mentioning.

The thing to be kept in mind is that, when the exec family of system calls are used, the original program will no longer be running after the new one is started.

查看更多
聊天终结者
6楼-- · 2020-01-26 05:13

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 :-).

查看更多
【Aperson】
7楼-- · 2020-01-26 05:15

To create a process:

  • fork(2), a system call directly to the kernel

To execute a program, replacing the current image:

  • execve(2), a system call directly to the kernel, usually just called exec

To wait for a child process to finish:

  • wait(2), a system call directly to the kernel

To run a program in a shell in a child process and wait for it to finish:

  • system(3), a library function

To get the man pages for all of the above:

   $ man 2 fork execve wait
   $ man 3 system
查看更多
登录 后发表回答