有人能用here-string来解释下面的行为吗?
$ echo "$SHLVL $BASH_SUBSHELL $BASHPID $$"
1 0 18689 18689
$ cat <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
1 0 19078 18689
$ cat <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
1 0 19079 18689BASHPID不同于here-string中的shell PID,并且每次都会改变,但我不明白为什么。在这里-document中也发生了同样的事情:
$ cat << EOT
> $SHLVL $BASH_SUBSHELL $BASHPID $$
> EOT
1 0 19096 18689令人惊讶的是,BASHPID在命令组中不会改变:
$ { cat ;} <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
1 0 18689 18689另一方面,它在子subshell中发生变化
$ (echo $BASHPID ; cat) <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
20465
1 1 20465 18689而here-string应该在当前shell中展开。
注意:我的bash版本是4.3+
发布于 2020-12-20 22:11:41
(只是猜测...)
其行为类似于以下内容:
# echo $$
35130
# echo $( echo $$ $BASHPID )
35130 88025
# echo $( echo $$ $BASHPID )
35130 88026
#
# # or
#
# echo $$ $BASHPID | cat
35130 88028
# echo $$ $BASHPID | cat
35130 88030显然,$BASHPID不是与$$同时扩展的。根据man bash的说法
BASHPID
展开为当前bash进程的进程ID。这在某些情况下不同于 $$ ,例如不需要重新初始化bash的subshell。
这意味着在Bash解析命令行时,$BASHPID不会扩展,否则它将与$$相同。在Bash源代码中有一个函数initialize_dynamic_variables() (在文件variables.c中):
1905 static void
1906 initialize_dynamic_variables ()
1907 {
1908 SHELL_VAR *v;
1909
1910 v = init_seconds_var ();
1911
1912 INIT_DYNAMIC_VAR ("BASH_ARGV0", (char *)NULL, get_bash_argv0, assign_bash_argv0);
....
....
1924 INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
1925 VSETATTR (v, att_integer);
....如图所示,像BASHPID这样的变量被称为动态变量。我猜这些var是经过特殊处理的,当它知道不会再派生更多的子shell时,它们会在最后一分钟被扩展(派生之后可能是exec(),例如,运行外部命令)。
https://stackoverflow.com/questions/65379351
复制相似问题