Difference between "system" and "exec" in Linux?

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

+61
c linux fork exec
Nov 08 '09 at 18:29
source share
12 answers

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

With system() your program continues to run, and you return the status of the external command that you called. Using exec() erases your process.

In general, I think you could think of system() as a higher level interface. You can duplicate your functions yourself using a combination of fork() , exec() and wait() .

To answer your last question, system() calls the creation of a child process, but in exec() does not. For this you will need to use fork() .

+81
Nov 08 '09 at 18:33
source share

The exec function replaces the current image of the process upon successful completion; no child is created (unless you have done this previously with fork() ). The system () function executes the fork child process and returns when the command completes or an error occurs.

+18
Nov 08 '09 at 18:33
source share

system() will execute the provided command in the child process that it spawns. exec() will replace the current process with a call to the new executable that you specify. If you want to create a child process using exec , you will need fork() to execute your process in advance.

+6
Nov 08 '09 at 18:34
source share

To create a process:

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

To execute a program by replacing the current image:

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

Waiting for the child process to complete:

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

To run a program in a shell in a child process and wait for its completion:

  • system(3) , library function

To get man pages for all of the above:

  $ man 2 fork execve wait $ man 3 system 
+6
Nov 09 '09 at 1:06
source share

system () will call your system default shell, which will execute the command line passed as an argument, which itself may or may not create additional processes that will depend on the command and system. In any case, at least a shell process will be created.

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

Basically they are completely different, used for different purposes. Additionally, exec () replaces the calling process and does not return. A more useful comparison would be between system () and spawn (). Although the system may be easier to call, it returns a value that tells you whether the command shell has been called and says nothing about the success of the command itself. With spawn () you can get the exit code of the process; by agreement other than zero, is used to indicate error conditions. Like exec (), spawn () should call the executable, not the shell script or inline command.

+2
Nov 08 '09 at 21:55
source share



 int system(const char *cmdstring); 

Example: system("date > file");




Typically, a system is implemented by calling fork, exec, and waitpid ; there are three types of return values.

  • If either fork fails or waitpid returns an error other than EINTR, the system returns -1 with errno to indicate an error.
  • If exec does not work, assuming that the shell cannot be executed, the return value will be as if the shell had executed exit (127).
  • Otherwise, all three functions-fork, exec and waitpid-success and the return value from the system are the shell completion status, in the format specified for waitpid.

The fork function is designed to create a new process (child), which then calls another program that calls one of the exec functions. When a process calls one of exec, this process is completely replaced by the new program, and the new program starts execution according to its main function. The process identifier does not change throughout exec because a new process is not created; Exec simply replaces the current process โ€” its text, data, heap, and stack segments โ€” with a completely 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 []); 



+2
Sep 19 '16 at 9:02
source share

exec () replaces the current current process with the process image of the function being executed .. only with this can executable files be called.

system () implicitly starts a new process to service the request and returns the value obtained using the child process that it was originally looking for. It uses the default shell to perform the operation.

+1
Feb 09 '12 at 4:00
source share

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

However, a not so subtle difference arises when you want to start a procedure, and then return to the existing code, having received a return code from the called procedure. system() provides a return code, but the return code can only be used to detect an error condition and cannot be used to restore the return code.

Possible correct sequence of system calls:

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

This subtlety includes other subtleties that can be determined by carefully reading the corresponding manual pages, but this code will work fine if there are no signals, several child processes, etc. In addition, inline declarations may limit the scope of variables, but are included so that this code is used as a template that works (you can use a different coding style :-).

+1
Dec 15 '14 at 18:34
source share

System () will create a child process and call another subclass, while exec () will not create a child process. As a result, the example will clear the difference.

some code ...

exec ('ls -l')

echo "1 2 3" // This will not be executed in bash (since the exec command uses the same shell)

some code ...

(ls -l) echo "1 2 3" // This will be done after the completion of the System child process, since they are different from the parent PID.

0
Jul 24 '12 at 18:28
source share

system () calls the required program or built-in command using the shell, this is inefficient because the shell starts before the program starts.

In the case of the exec family of system calls, a completely new image is created, that is, they replace the current process with the new process specified in the path or file, or any argument you mention.

Keep in mind that when the exec family of system calls is used, the original program will no longer start after starting a new one.

0
May 10 '14 at 10:34
source share

In general, the โ€œsystemโ€ is so inefficient, and you should not use it unless you have a little code. If you need to execute several programs in your process, you are better off using fork & exec, although you make it more complex. Here is a list of the differences between them:

Team

1- "system" creates a copy of the shell to execute your program. Each time you call the system, you create a copy of the shell. Therefore, do not use it when you have many programs to execute inside your process.

2- In particular, if you want to perform 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 the system calls the shell to execute your desired program, you may have problems with user rights. For example, someone might crack your code and execute something else instead of the program that you plan to execute with a system command.

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

0
Sep 04 '15 at 18:42
source share

JonSpencer's answer is good, except that child_status must be int (no pointer to int) and must be passed to the wait function by reference.

So, the code will be basically the same, just changing these two 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 } } } } 

(Note that I donโ€™t have enough reputation yet to comment on Jon post, so I edited it. Some people rejected the publication in which I wanted to answer the question and not edit it, but I think that is much easier in this case , itโ€™s practical and clear to edit existing code, just fixing a small mistake, than writing a full copy / paste / modify answer.) In any case, thanks to JonSpencer for your answer, it was really useful for me!

0
Sep 14 '15 at 13:34 on
source share



All Articles