根据我的阅读,将命令放在括号中应该在子shell 中运行它,类似于运行脚本。如果这是真的,如果 x 未导出,它如何查看变量 x?
x=1
Run Code Online (Sandbox Code Playgroud)
(echo $x)
在命令行上运行结果为 1
echo $x
正如预期的那样,在脚本中运行不会产生任何结果
我理解子shell的语法是(<commands...>)
,$()
只是一个可以从中检索变量值的子shell?
注意:根据文档中的不同措辞,这适用于 bash 4.4。
根据this和this,子shell是通过使用括号启动的(…)
。
( echo "Hello" )
Run Code Online (Sandbox Code Playgroud)
echo "Hello" &
Run Code Online (Sandbox Code Playgroud)
Posix 规范在本页中使用了这个词subshell
,但没有定义它,而且,在同一页上,也没有定义“子进程”。
两者都使用核fork()
函数,对吗?
那么将一些叉称为“子外壳”而将其他一些叉称为“子进程”的确切区别是什么。
$ unset foo
$ unset bar
$ echo $foo
$ echo $bar
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
$ foo=a
$ bar=b
$ export bar
$ echo $foo
a
$ echo $bar
b
$ PATH=
$ echo $PATH
$ /bin/bash
bash: lesspipe: No such file or directory
bash: dircolors: No such file or directory
bash: ls: No such file or directory
$ echo $foo
$ echo $bar
b
$ echo $PATH
$
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,更改$PATH
会影响子shell,而另一个变量需要被export
编辑。为什么?
我刚刚意识到history
在子 shell 中不会输出任何内容。我将尝试通过计算行数来显示 - 首先使用 echo 进行健全性检查:
$ echo a | wc -l
1
Run Code Online (Sandbox Code Playgroud)
...并在子外壳中:
bash -c 'echo a' | wc -l
1
Run Code Online (Sandbox Code Playgroud)
事实上,我们期望在这两种情况下都有一行输出。现在,对于history
:
$ history | wc -l
681
Run Code Online (Sandbox Code Playgroud)
...但在子外壳中:
$ bash -c 'history' | wc -l
0
Run Code Online (Sandbox Code Playgroud)
...history
不返回任何行。
为什么会发生这种情况 - 如何history
在子 shell 中输出当前 shell 的历史记录(包括最后一个会话命令)?
AFAIK,cat
是一个外部命令,它在执行时分叉出一个新进程,就像sh -c
或执行脚本一样。话虽如此,我希望cat
使用它的命令环境,因为它被其他外部命令使用,比如
f=test.txt sh -c 'cat "$f"'
Run Code Online (Sandbox Code Playgroud)
这不应该显示文件的内容吗
f=test.txt cat $f
Run Code Online (Sandbox Code Playgroud)
?
注意:我不是在问什么是 someVariable=someValue command
. 我在问为什么第一个例子使用它的命令变量而不是第二个。变量扩展在第二个例子中发生的方式它应该在第一个例子中发生。