Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么BASHPID会在这里变化_Bash - Fatal编程技术网

为什么BASHPID会在这里变化

为什么BASHPID会在这里变化,bash,Bash,有人能用here字符串解释以下行为吗 $ 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

有人能用here字符串解释以下行为吗

$ 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
在命令组中没有改变:

$ { cat ;} <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
1 0 18689 18689
${cat;}(只是猜测…)

其行为与此类似:

#echo$$
35130
#echo$(echo$$$BASHPID)
35130 88025
#echo$(echo$$$BASHPID)
35130 88026
#
##或
#
#echo$$$BASHPID|猫
35130 88028
#echo$$$BASHPID|猫
35130 88030
显然,
$BASHPID
没有与
$
同时展开。根据man bash

巴什皮德

扩展到当前bash进程的进程ID在某些情况下,这不同于
$
,例如不需要重新初始化bash的子shell

这意味着在Bash解析命令行时,
$BASHPID
不会展开,否则它将与
$$
相同。在Bash源代码中有一个func
initialize\u dynamic\u variables()
(在文件
variables.c
中):


如图所示,像
BASHPID
这样的变量称为动态变量。我猜这些变量是经过专门处理的,并且在最后一分钟进行了扩展,因为它知道不再需要派生子shell(派生之后可能会有
exec()
,例如,运行外部命令).

不应创建子进程
该子进程是为
cat
创建的。您可以比较
cut-d''-f1-在我的系统(Ubuntu)上没有
/usr/lib/bash/
。你的bash版本是什么?我想我的archlinux正在做这些,试试
/usr/lib*/bash
中的任何一个。在我的系统上,bash安装了示例可加载内置程序。Bash5.1.0。它们来自。好的。我推断,
BASHPID
对于外部命令来说,这种奇怪的事情会持续到bash5+。我想这是关于上下文解析顺序。关于前半部分的回答:是的,这就是为什么我们有
$$
$BASHPID
。其次,
BASHPID
实际上是一个动态变量。它可能在特殊时刻被扩展,但为什么首先要使用
cat
PID,因为
cat
不是子shell而是子流程?这是指变量本身,而不是扩展。该引号表示在子shell中,$$和$BASHPID具有不同的值。@Edouard子shell通过调用
execve
,将自身替换为
cat
,在此文档中,因此$BASHPID在此之前展开。@Ed那里有一个子shell,子shell将任何内容放入临时文件中,通过
dup2
打开并重定向到stdin,然后取消临时文件的链接并调用
execve
@oguz-yes。我习惯于检查
$BASHPID
以了解变量的作用域。下面是我们问题的一个有趣应用:
cat
$ { cat ;} <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
1 0 18689 18689
$ (echo $BASHPID ; cat) <<< "$SHLVL $BASH_SUBSHELL $BASHPID $$"
20465
1 1 20465 18689
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);
....