网站搜索

了解 Bash 中 $$和 $BASHPID 之间的区别


最近,我正在编写一个 shell 脚本,我发现 bash 特殊变量 $BASHPID 的行为存在显着差异。 Linux 中运行的每个进程都会分配一个进程ID,这就是操作系统处理进程的方式。

同样,您的 bash 终端会话也将被分配一个进程 ID。有一个名为 "$""$BASHPID" 的特殊变量,用于存储当前 shell 的进程 ID。

继续运行以下命令来查看当前 shell 的进程 ID 是什么。 "$""$BASHPID" 将返回相同的值。

echo $$               # Printing special variable $
echo $BASHPID         # Printing the varibale $BASHPID

在bash中,当我们从shell调用任何外部程序时,它会创建一个子进程/子shell,并且该程序将仅在子进程中提交。请参阅下面的示例,其中我在名为 “sample.sh” 的脚本中放置了一个简单的进程监视器命令,以演示父 shell 如何创建子 shell 来运行程序。

#!/usr/bin/env bash

ps -ef --forest | grep -i bash

现在运行这个脚本我们可以获得bash的进程ID。从下图中,您可以了解当我调用脚本 bash 时会创建一个子进程并运行该脚本。

./sample.sh

现在让我们在脚本中使用 "$""$BASHPID" 并看看它返回什么。

#!/usr/bin/env bash
echo "============================"
ps -ef --forest | grep -i bash
echo "============================"
echo "PID USING $ FOR SCRIPT $0 ==> $$"
echo "PID USING BASHPID FOR SCRIPT $0 ==> $BASHPID"
echo

现在再次运行该脚本。

./sample.sh

好吧,它返回相同的进程 ID。真正的区别来了。让我们通过在括号() 内运行命令来在脚本内创建另一个子进程。

STORING THE PID INTO A VARIABLE…

VAR_HASH=$(echo $$)
VAR_BASHPID=$(echo $BASHPID)

echo "VALUE OF VAR_HASH ==> $VAR_HASH"
echo "VALUE OF VAR_BASHPID ==> $VAR_BASHPID"

在 bash 中,括号将调用子进程并运行括号内的任何内容。在这种情况下,$$BASHPID 都应该存储新的子进程 ID。但从上图中,您可以看到有一个区别,其中 $ 存储 382,这是父 ID(脚本 sample.sh 的进程 ID) ),$BASHPID 存储由括号创建的子进程 ID。

现在让我们尝试理解这种行为。我们将查看手册页的内容。

man bash

当您使用 $ 时,即使在子 shell 中,它也会存储创建它的父进程的进程 ID。但是 BASHPID 将存储当前进程 ID,即当在括号内调用时,它将存储子进程 ID。

我们无法分配或修改变量$,但是BASHPID可以重新分配,但没有效果。

$=10
BASHPID=10
echo $BASHPID

可以取消设置BASHPID。当您取消设置时,它会失去其特殊状态,并且您也可以开始将其用作普通变量。

unset BASHPID
echo $BASHPID
BASHPID="Tecmint"
echo $BASHPID

即使您尝试分配 shell 的进程 ID,它也会被视为用户定义的变量,因为它已经失去了其特殊状态。

BASHPID=$(echo $$)
echo $$;echo $BASHPID

在这种情况下,您必须使用 BASHPID 的新终端会话来获取其特殊状态。

这就是本文的内容。我们已经在本文中了解了 $BASHPID 之间的区别以及它们的行为方式。阅读本文并与我们分享您的宝贵反馈。