如果运行没有path的命令,子shell是不会创build的?

我正在阅读“ Linux命令行和Shell脚本圣经 ”第3版。 在279页,在这里我引用:

“命令replace创build了所谓的subshell来运行封闭的命令,子shell是一个独立的子shell,由运行脚本的shell生成,因此,在脚本中创build的任何variables都不可用于subshel​​l命令。

如果您使用./path从命令提示符运行命令,也会创build子./ ,但是如果只是不使用path运行命令,则不会创build它们。

最后一句话让我感到困惑。 我testing了一个简单的脚本,输出一些variables; 在脚本存在后,variables不会持续,但脚本是从./path调用的,或者将脚本放在/usr/bin然后运行而不用path。 在我看来,它是如何调用关于subshel​​l没有区别。

我错过了什么?

“命令replace创build了所谓的子shell来运行封闭的命令。子shell是一个独立的子shell,由运行脚本的shell生成。

这是在谈论build设如:

 echo "$(date) `uname -r`" 

在这个例子中,我使用两种不同的subhells支持符号来调用两个子壳体。 第一个子shell运行date命令,第二个子shell运行uname命令。 两个子壳终止后, echo命令由原始shell执行。

因此,您在脚本中创build的任何variables都不可用于subshel​​l命令。

这里作者把它倒过来了。 调用子shell之前创build的variables可用于子shell。 在子shell中创build的variables只能在子shell中使用,一旦子shell终止,variables就会消失。

如果您使用./path从命令提示符运行命令,也会创build子壳,但是如果只是不使用path运行命令,则不会创build它们。

作者在这里想说什么是非常不清楚的。 如果您调用外部命令,则不pipe是否使用path调用,都会发生以下情况:

  • shell fork创build一个新进程。
  • 新创build的subprocess执行您可能指定的任何I / Oredirect。
  • subprocessexecve外部命令,在这一点上进程不再是一个shell,成为外部程序。 (这当然可以是一个shell脚本)。

这是一个新的过程,所以外部命令设置的任何variables对于父进程都是不可用的,就像它们是一个子shell一样。

作者可能指的是以下三种情况之一:

  • 外部命令是格式不正确的脚本,在这种情况下,调用shell可能会通过猜测使用哪个shell来解释脚本来解决不正确的格式问题。 (这种情况是不可预知的,我强烈build议不要依赖它。find解释器的正确方法是在脚本的开头有一个#!行)。
  • 您可能正在调用内部命令,例如read ,它在语法上看起来像通过searchPATHfind的外部命令。 但即使它在语法上看起来相同,它的行为也会有所不同。 由于read将设置一个variables,以便用于下面的命令, read本身必须在当前进程中发生,没有任何fork调用。 (即使内部命令可以安全地作为一个subprocess调用,由于性能的原因,在当前进程中可以更好地完成。调用fork是昂贵的。)
  • 您可能正在使用shell命令. file . filesource file 。 在这种情况下, file不是脚本,但它有点类似。 file所有命令都将由当前shell调用,而不首先调用fork 。 (但是,当然, file内的命令可以触发fork调用)。 在这种情况下,任何#! file行将被忽略,并且由file设置的任何variables将可用于当前shell。