Linux中“系统”和“执行”的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1697440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:52:49  来源:igfitidea点击:

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

clinuxexecfork

提问by Kamil

What is the difference between systemand execfamily commands? Especially I want to know which one of them creates child process to work?

systemexec家庭命令有什么区别?特别是我想知道其中哪一个创建了子进程来工作?

回答by BobbyShaftoe

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.

exec 函数在成功时替换当前运行的进程映像,不会创建子进程(除非您自己之前使用fork())。system() 函数确实 fork 一个子进程,并在提供的命令完成执行或发生错误时返回。

回答by Carl Norum

system()calls out to shto 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.

system()调用 tosh来处理你的命令行,所以你可以得到通配符扩展等 exec(),它的朋友用一个新的进程映像替换当前的进程映像。

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

使用system(),您的程序将继续运行,并且您会返回有关您调用的外部命令的一些状态。使用exec(),您的过程将被抹去。

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

一般来说,我想您可以将其system()视为更高级别的接口。您可以使用某种组合fork()exec()、 和自己复制其功能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.

回答你的最后一个问题,system()导致创建一个子进程,而exec()家庭没有。你需要使用fork()它。

回答by Timo Geusch

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.

system()将在它产生的子进程中执行提供的命令。exec()将使用您指定的新可执行文件的调用替换当前进程。如果要使用 生成子进程exec,则必须fork()事先创建进程。

回答by Clifford

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.

system() 将调用您的系统默认命令外壳,它将执行作为参数传递的命令字符串,它本身可能会也可能不会创建进一步的进程,这取决于命令和系统。无论哪种方式,至少会创建一个命令 shell 进程。

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.

使用 system() 可以调用任何命令,而使用 exec() 只能调用可执行文件。Shell 脚本和批处理文件必须由命令 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.

基本上它们是完全不同的,用于不同的目的。而且 exec() 代替了调用过程,并且不返回。一个更有用的比较是在 system() 和 spawn() 之间。虽然 system 可能更容易调用,但它返回一个值,告诉您是否调用了命令外壳程序,而不会告诉您命令本身是否成功。使用 spawn() 可以获得进程的退出代码;按照惯例,非零用于指示错误条件。像 exec() spawn() 必须调用可执行文件,而不是 shell 脚本或内置命令。

回答by DigitalRoss

To create a process:

要创建流程:

  • fork(2), a system call directly to the kernel
  • fork(2), 直接对内核的系统调用

To execute a program, replacing the current image:

要执行程序,替换当前图像:

  • execve(2), a system call directly to the kernel, usually just called exec
  • execve(2),直接向内核的系统调用,通常只是调用 exec

To wait for a child process to finish:

等待子进程完成:

  • wait(2), a system call directly to the kernel
  • wait(2), 直接对内核的系统调用

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

要在子进程的 shell 中运行程序并等待它完成:

  • system(3), a library function
  • system(3), 库函数

To get the man pagesfor all of the above:

要获取上述所有内容的手册页

   $ man 2 fork execve wait
   $ man 3 system

回答by Morpheus

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

exec() 用正在执行的函数的进程映像替换当前正在运行的进程。使用它只能调用可执行文件。

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.

system() 隐式地分叉一个新进程来为请求提供服务,并返回它通过它最初分叉的子进程获得的值。它使用系统的默认 shell 来执行操作。

回答by Poseidon_Geek

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

System() 将创建子进程并调用另一个子 shell,而 exec() 不会创建子进程。给定示例将清楚区别。

some code...

一些代码...

exec('ls -l')

exec('ls -l')

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

echo "1 2 3" // 这不会在 bash 中执行(因为 exec 命令使用相同的 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.

system (ls -l) echo "1 2 3" // 这将在完成系统子进程后执行,因为它们与父 PID 不同。

回答by kishanp

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.

system() 使用 shell 调用所需的程序或内置命令,这是一种低效的方式,因为 shell 在程序启动之前就已启动。

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.

在 exec 系列系统调用的情况下,正在创建一个全新的映像,也就是说,它们用路径或文件或您提到的任何参数指定的新进程替换当前进程。

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.

需要注意的是,当使用 exec 系列系统调用时,新程序启动后,原程序将不再运行。

回答by Jon Spencer

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.

exec(2)和之间存在一些显着差异system(3),应牢记这一点。 system()返回给调用者,而exec()用新图像替换现有代码。这在上面已经解释过。

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.

但是,当您想要运行一个过程然后返回到现有代码,从被调用的过程接收返回代码时,就会出现不太细微的区别。 system()确实提供了返回码,但返回码只能用于检测错误情况,不能用于恢复返回码。

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

这个序列还有其他微妙之处,可以通过仔细阅读相关手册页来确定,但是在没有信号、多个子进程等的情况下,这段代码也能正常工作。此外,内联声明可能会限制变量,但包含在内是为了允许将此代码用作有效的模板(您可以使用不同的编码风格 :-)。

回答by ImanKh

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:

一般来说,“系统”效率很低,除非你有一个小代码,否则你不应该使用它。如果你需要在你的进程中执行多个程序,你最好使用 fork&exec 虽然你使它更复杂。以下是它们之间的差异列表:

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.

1-“系统”命令创建一个shell副本来执行你的程序。每次调用系统时,都会创建一个 shell 副本。所以当你的进程中有很多程序要执行时,不要使用它。

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

2- 具体来说,如果你想执行“mv”、“mkdir”等系统函数,最好使用mkdir()、unlink()或remove()等例程,而不是通过“system(” rm ....") 或 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.

3- 由于系统调用 shell 来执行您想要的程序,您可能会遇到一些用户权限问题。例如,有人可能会破解您的代码并执行其他内容,而不是您打算通过系统命令执行的程序。

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

有关更多信息,您可以阅读本书的第 11 章:David Curry 的“UNIX 系统编程”。