ウェブサイト検索

Bash の $$と $BASPID の違いを学ぶ


最近、シェル スクリプトに取り組んでいたところ、bash 特殊変数 $BASPID の動作に大きな違いがあることに気づきました。 Linux で実行されているすべてのプロセスにはプロセスIDが割り当てられ、それがオペレーティング システムによるプロセスの処理方法です。

同様に、bash ターミナル セッションにもプロセス ID が割り当てられます。現在のシェルのプロセス ID を格納する "$" および "$BASHPID" という特別な変数があります。

以下のコマンドを実行して、現在のシェルのプロセス ID を確認してください。 "$""$BASHPID" はどちらも同じ値を返します。

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

bash では、シェルから外部プログラムを呼び出すと、子プロセス/サブシェルが作成され、プログラムは子プロセス内でのみ送信されます。以下の例を参照してください。「sample.sh」 というスクリプトに簡単なプロセス モニター コマンドを入れて、親シェルがプログラムを実行するためのサブシェルを作成する方法を示しています。

#!/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 が返されます。ここからが実際の違いです。 parentheses() 内でコマンドを実行して、スクリプト内に別の子プロセスを作成しましょう。

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 では、括弧は子プロセスを呼び出し、括弧内にあるものをすべて実行します。その場合、$$BASPID の両方に新しい子プロセス ID を格納する必要があります。しかし、上の画像から、 $ が親 ID (スクリプト sample.sh382 を格納する場所に違いがあることがわかります。 Strong>)、$BASPID には、括弧で囲まれた作成された子プロセス ID が格納されます。

では、この動作を理解してみましょう。 man ページに何が記載されているかを見てみましょう。

man bash

$ を使用すると、サブシェル内であっても、作成元の親プロセスのプロセス ID が保存されます。ただし、BASPID は現在のプロセス ID を保存します。つまり、括弧内で呼び出された場合は、子プロセス ID が保存されます。

変数 $ を割り当てたり変更したりすることはできませんが、BASHPID は再割り当てできますが、効果はありません。

$=10
BASHPID=10
echo $BASHPID

BASPID の設定を解除することができます。設定を解除すると、その特別な状態が失われ、これを通常の変数として使用し始めることができます。

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

シェルのプロセス ID を割り当てようとしても、すでに特別な状態を失っているため、ユーザー定義変数として扱われます。

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

この場合、BASPID の特別な状態を取得するには、新しいターミナル セッションを使用する必要があります。

この記事はここまでです。この記事では、$BASPID の違いとそれらの動作について説明しました。この記事を読んで、貴重なフィードバックを私たちと共有してください。