Learning Bash Book 提到一个子shell只会继承环境变量和文件描述符等,不会继承没有导出的变量:
$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var
$
Run Code Online (Sandbox Code Playgroud)
据我所知,shell 将为()和 for创建两个子shell ./file,但是为什么在这种()情况下,子shell 会识别var变量,尽管它没有导出,而在这种./file情况下它没有识别?
# Strace for ()
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631
Run Code Online (Sandbox Code Playgroud)
我试图strace弄清楚这是如何发生的,令人惊讶的是我发现 bash 将对克隆系统调用使用相同的参数,所以这意味着分叉进程()和./file应该具有与父进程相同的进程地址空间,那么为什么在这种()情况下,变量是否对子外壳可见,并且这种情况不会发生./file,尽管相同的参数基于克隆系统调用?
I understand that when I run exit it terminates my current shell because exit command run in the same shell. I also understand that when I run exit & then original shell will not terminate because & ensures that the command is run in sub-shell resulting that exit will terminate this sub-shell and return back to original shell. But what I do not understand is why commands with and without & looks exactly the same under pstree, in this …
在研究有关 Bash 子 shell 的更深入信息时,我遇到了一个有趣的执行,我想了解它为何有效。执行涉及将字符串分配给变量,然后在man调用时使用该变量,链接到原始示例。我已经读过为什么LESS在该示例中使用特定变量(在许多发行版中man作为less默认分页器),我不明白的是命令执行后的变量赋值如何在没有任何类型的分隔元字符的情况下工作。
LESS=+/'OPTIONS' man manman直接在该部分下打开命令的手册页OPTIONS。它适用于直接使用less太打开的文件(这使我相信该LESS变量的使用less方式与在“会话”中进行正则表达式搜索相同less)。该LESS变量不会被导出,它永远不会保存在当前的 shell 环境中(执行不会echo $LESS返回任何内容),那么如何less捕获该值呢?
为什么这有效,但不是类似的东西foo='hello' echo $foo?;仅当变量赋值和命令执行之间包含命令分隔符 ( ) 时,这种情况才有效。我什至尝试过foo=+'hello' echo $foo以防万一=+在 Bash 中做了一些我不知道的事情,但输出没有变化。
欢迎任何解释或阅读材料!