【问题标题】:$> bash script.sh ... does the forked bash process in turn create a sub-shell?$> bash script.sh ... 分叉的 bash 进程是否又创建了一个子 shell?
【发布时间】:2014-08-27 22:44:40
【问题描述】:

如果我跑:

$> bash script.sh

fork-and-exec 恰好运行 bash 二进制文件。该进程是执行 script.sh 还是以与

相同的方式依次创建子 shell
$> ./script.sh 

首先创建一个子shell来执行脚本?

【问题讨论】:

  • 分叉和创建子shell是一回事。
  • 本质上,这两个命令之间的唯一区别是操作系统运行bash 并以script.sh 作为您的第一个参数(假设#!/bin/bash 的shebang)。

标签: bash shell subprocess subshell


【解决方案1】:

运行bash script.sh的bash进程直接执行脚本,而不是作为第二层fork和exec。显然,脚本中的各个命令是单独分叉和执行的,而不是脚本本身。

您可以使用ps 来表明这一点。例如,script.sh 可能包含:

tty
echo $$
sleep 20

您可以运行它并在另一个终端窗口中运行ps -ft tty0(如果tty 命令指示tty0),您会看到运行bash script.sh 命令的shell,即运行script.sh 和sleep 命令。

示例

在ttys000:

$ bash script.sh
/dev/ttys000
65090
$

在ttys001:

$ ps -ft ttys000
  UID   PID  PPID   C STIME   TTY           TIME CMD
    0  2422  2407   0  9Jul14 ttys000    0:00.13 login -pfl jleffler /bin/bash -c exec -la bash /bin/bash
199484  2428  2422   0  9Jul14 ttys000    0:00.56 -bash
199484 65090  2428   0  3:58PM ttys000    0:00.01 bash script.sh
199484 65092 65090   0  3:58PM ttys000    0:00.00 sleep 20
$

【讨论】:

    【解决方案2】:

    您可以使用pstree 或ps -fax 查看进程树。在您的情况下,当将 bash 指定为带有脚本参数的(分叉)命令时,它不会(不需要)分叉子外壳,因为使用“命令文件”运行是一种操作模式(如果不使用 -c)。

    顺便说一句:您也可以使用 exec sh script.sh 将您当前的 shell 进程替换为新的子 shell。

    当您调用没有source(或.)命令的shell 脚本时,它将在子shell 中运行。您的第二行就是这种情况。如果要在当前脚本中运行脚本,则需要使用. ./script.sh。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 2016-09-22
      • 2012-09-01
      • 2017-02-15
      • 2010-11-02
      相关资源
      最近更新 更多