【问题标题】:What happens if you run 'exec ls' in your shell and why? [closed]如果你在 shell 中运行 'exec ls' 会发生什么,为什么? [关闭]
【发布时间】:2013-01-11 08:54:09
【问题描述】:

问题是标题。我不明白为什么在执行“ls”后终端会立即关闭。 Linux shell 是这样的:

1.while (1) {
2. char *cmd = read_command();
3. int child_pid = fork();
4. if (child_pid == 0) {
5. 执行(cmd);
6.}其他{
7.waitpid(child_pid);
8.}
9.}

所以,如果我们在 shell 中运行 'exec ls',cmd 是一个 'exec ls' 的字符串。第 3 行创建了一个子进程。在第 5 行,exec(cmd) 将替换子进程,但不会影响父进程。如果父进程不受影响,那为什么终端会关闭呢?

请告诉我上述推理中的缺陷。

【问题讨论】:

  • 如果您正在运行bash,请输入help exec

标签: linux shell unix command-prompt


【解决方案1】:

如果你运行ls,你的shell进程会启动另一个进程来运行ls程序,然后它会等待它完成。完成后,控制权返回给 shell。

使用exec ls,您实际上替换使用ls 程序在当前 进程中的shell 程序,这样,当它完成时,没有shell 等待它。

最有可能的是,您将拥有一个终端程序或init 作为父进程,这将在您的进程退出时接管。这就是你的 shell 消失的原因,因为你明确告诉了它。

有关shell/ls(非执行)情况的说明,请参阅this answer


至于您的更新,shell 确实总是创建一个单独的进程来做事。有大量的内部命令(例如cdalias)不涉及创建其他进程(这当然取决于您的shell,但是作为一个示例,您可以看到bash 内部命令在命令提示符下输入man bash-builtins)。

exec 就是其中之一。它只是用您指定的程序替换 shell 本身(即,不是分叉的子进程)。这就是为什么它不像你想象的那样运行。

【讨论】:

  • 谢谢!我更新了刚才的问题,更清楚地描述了我的困惑。请再读一遍好吗?
  • @zcb,请参阅更新后的答案。 Shell 并不总是为每个命令运行一个子进程。 execcdalias 等会影响 current shell。 exec 是对 shell(在 current 进程中)的显式请求以替换自身。有关示例,请参阅man bash-builtins
  • 哦,我终于明白了!非常感谢!
【解决方案2】:

Exec 用另一个进程覆盖当前进程。通常,当您调用“ls”时,会创建一个作为 shell 的子进程运行的新进程。 “exec ls”用“ls”进程覆盖你当前的shell。因此,一旦“ls”终止,您的终端就会关闭。

【讨论】:

  • 你的意思是shell特别对待命令'exec *'?你的意思是:shell 不会为 'exec *' 派生一个子进程,同时覆盖自身?如果这是真的,为什么 shell 会以不同的方式处理此类命令?
  • 确实如此。 exec 是一个内置的 shell 命令,它不会派生新进程而是覆盖自身。
【解决方案3】:

exec 用新的进程映像覆盖正在运行的进程。因此,在您当前的进程中,您正在运行的 shell 被ls 可执行映像覆盖,一旦ls 退出,该进程就会关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-05
    • 2017-08-19
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 2016-09-14
    • 2021-01-16
    相关资源
    最近更新 更多