我正在阅读“ Linux命令行和Shell脚本圣经 ”第3版。 在279页,在这里我引用:
“命令replace创build了所谓的
subshell来运行封闭的命令,子shell是一个独立的子shell,由运行脚本的shell生成,因此,在脚本中创build的任何variables都不可用于subshell命令。如果您使用
./path从命令提示符运行命令,也会创build子./,但是如果只是不使用path运行命令,则不会创build它们。
最后一句话让我感到困惑。 我testing了一个简单的脚本,输出一些variables; 在脚本存在后,variables不会持续,但脚本是从./path调用的,或者将脚本放在/usr/bin然后运行而不用path。 在我看来,它是如何调用关于subshell没有区别。
我错过了什么?
“命令replace创build了所谓的子shell来运行封闭的命令。子shell是一个独立的子shell,由运行脚本的shell生成。
这是在谈论build设如:
echo "$(date) `uname -r`"
在这个例子中,我使用两种不同的subhells支持符号来调用两个子壳体。 第一个子shell运行date命令,第二个子shell运行uname命令。 两个子壳终止后, echo命令由原始shell执行。
因此,您在脚本中创build的任何variables都不可用于subshell命令。
这里作者把它倒过来了。 调用子shell之前创build的variables可用于子shell。 在子shell中创build的variables只能在子shell中使用,一旦子shell终止,variables就会消失。
如果您使用./path从命令提示符运行命令,也会创build子壳,但是如果只是不使用path运行命令,则不会创build它们。
作者在这里想说什么是非常不清楚的。 如果您调用外部命令,则不pipe是否使用path调用,都会发生以下情况:
fork创build一个新进程。 这是一个新的过程,所以外部命令设置的任何variables对于父进程都是不可用的,就像它们是一个子shell一样。
作者可能指的是以下三种情况之一:
#!行)。 read ,它在语法上看起来像通过searchPATHfind的外部命令。 但即使它在语法上看起来相同,它的行为也会有所不同。 由于read将设置一个variables,以便用于下面的命令, read本身必须在当前进程中发生,没有任何fork调用。 (即使内部命令可以安全地作为一个subprocess调用,由于性能的原因,在当前进程中可以更好地完成。调用fork是昂贵的。) . file . file或source file 。 在这种情况下, file不是脚本,但它有点类似。 file所有命令都将由当前shell调用,而不首先调用fork 。 (但是,当然, file内的命令可以触发fork调用)。 在这种情况下,任何#! file行将被忽略,并且由file设置的任何variables将可用于当前shell。