首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么BASHPID在here-strings中改变

为什么BASHPID在here-strings中改变
EN

Stack Overflow用户
提问于 2020-12-20 19:24:12
回答 1查看 61关注 0票数 0

有人能用here-string来解释下面的行为吗?

代码语言:javascript
复制
$ 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 18689

BASHPID不同于here-string中的shell PID,并且每次都会改变,但我不明白为什么。在这里-document中也发生了同样的事情:

代码语言:javascript
复制
$ cat << EOT
> $SHLVL $BASH_SUBSHELL $BASHPID $$
> EOT
1 0 19096 18689

令人惊讶的是,BASHPID在命令组中不会改变:

代码语言:javascript
复制
$ { cat ;} <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
1 0 18689 18689

另一方面,它在子subshell中发生变化

代码语言:javascript
复制
$ (echo $BASHPID ; cat) <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
20465
1 1 20465 18689

而here-string应该在当前shell中展开。

注意:我的bash版本是4.3+

EN

回答 1

Stack Overflow用户

发布于 2020-12-20 22:11:41

(只是猜测...)

其行为类似于以下内容:

代码语言:javascript
复制
# 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中):

代码语言:javascript
复制
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(),例如,运行外部命令)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65379351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档