1. ホーム
  2. スクリプト・コラム
  3. リナックスシェル

シェルスクリプトでよく使われる組み込み変数(Bash組み込み変数)

2022-01-05 16:56:15

funcname, $lineno, $pwd

FUNCNAME LINENO 変数は、スクリプトのデバッグによく使用されます

FUNCNAME 現在の関数名を示す。スコープは関数内に限定され、関数の外では値を持たない。

LINENO 現在のスクリプトで変数が出現する行番号を示します。

PWD はカレントディレクトリを示し、それに対応する pwd コマンド

既存のスクリプトがあります a.sh それは次のように読みます。

#! /bin/bash

   testa()
  {
    echo 'func='$FUNCNAME,$LINENO
   }
  testa
 
  echo 'lineno:'$LINENO
  echo 'xx:'$FUNCNAME
  echo 'curpath:'$PWD

実行 . /a.sh コマンドを実行すると、次のような出力が得られます。

<ブロッククオート

[tt@ecs-centos-7 ~]$ . /a.sh
func=testa,6
リネン:12
xxです。
curpath:/home/tt

での testa 関数の中で FUNCNAME 変数の値は testa これは関数の名前であり、関数の外では値を持ちません。

LINENO 関数内外の変数が、現在の行番号を示す

$$, $PPID

この二つの変数は、現在のプロセス ID と親プロセス ID を順に表します。

既存の a.sh スクリプトで、次のように読みます。

sleep 20 sleep文は、スクリプトの実行プロセスを保留して、別の端末で出力を確認するために使用されます。

#! /bin/bash
#set -u

echo 'cur pid:'$$
echo 'parent pid:'$PPID
sleep 20

実行 . /a.sh で、結果は次のようになります。

[tt@ecs-centos-7 ~]$ . /a.sh 
cur pid:13095
parent pid:12982

を実行した後 a.sh スクリプトのプロセスが終了する前に、別のターミナルを開き、次のように実行します。 ps -o pid,ppid,time,cmd -p 12982,13095 コマンドを実行すると、次のような結果が得られます。

[tt@ecs-centos-7 ~]$ ps -o pid,ppid,time,cmd -p 12982,13095
  PID PPID TIME CMD
12982 12981 00:00:00 -bash
13095 12982 00:00:00 /bin/bash . /a.sh

上記の結果からわかるように、実行された . /a.sh コマンドを使用すると <マーク スクリプト 13095 であり、12982 はその親プロセス ID であり、これは a.sh 変数で、現在の bash インスタンスの値です。

$0,$1,$2... $n, $#

PPID コマンドラインからスクリプトに渡されたパラメーターの数を示す。

$# はコマンドラインからスクリプトに渡される引数です $0,$1,$2... $n はスクリプト自体の名前です。
$0 は最初のパラメータ
$1 は2番目のパラメータで、以下同様です。
$2 はn番目のパラメータ

10番目以降の引数は中括弧で囲む必要があります。例えば、10番目の変数、11番目の変数、12番目の変数の順に、${10}, ${11}, ${12}と記述します。

$*, $@

どちらも位置パラメータを表しますが、いくつかの違いがあります。

を使用すると $n 二重引用符を含む場合、つまり$*の形の場合は、すべての位置引数は1つの単語として扱われ、二重引用符を含まない場合、つまり$*の形の場合は、それぞれの位置引数は別々の単語として扱われます

また $* 引数の各位置は、二重引用符で囲まれているかどうかにかかわらず、別々の単語として扱われます。

既存の $@ と読みます。

c.sh

実行 #! /bin/bash cnt=1 echo 'test 1111' for var in "$*" do echo "arg$cnt="$var let "cnt+=1" done echo cnt=1 echo 'test 2222' for var in $* do echo "arg$cnt="$var let "cnt+=1" done echo cnt=1 echo 'test 3333' for var in "$@" do echo "arg$cnt="$var let "cnt+=1" done echo cnt=1 echo "test 4444" for var in $@ do echo "arg$cnt="$var let "cnt+=1" done で、結果は次のようになります。

[root@ecs-centos-7 ~]# . /c.sh 1 2 3
テスト 1111
arg1=1 2 3

テスト2222
arg1=1
arg2=2
arg3=3

テスト3333
arg1=1
arg2=2
arg3=3

テスト 4444
arg1=1
arg2=2
arg3=3

上記の結果からわかるように、$*の場合、二重引用符が追加された後は、すべての位置引数が1つの単語として扱われます

については、ダブルクォートの有無にかかわらず、結果は同じです。

つまり、$*と$@の違いは、ダブルクォートを使用した場合のみです

$?

コマンド、関数、スクリプトの終了ステータス。コマンドの実行結果や関数の呼び出し結果を判断する際に有用です。

既存の . /c.sh 1 2 3 e.sh テストスクリプト

e.shスクリプト

f.sh

f.shスクリプト

#! /bin/bash

test_func()
{
  if [[ $1 -eq 10 ]]; then
        return 5
  fi
  return 6
}


if [ $# -ge 1 ]; then
   name="$1"
   shift 1
   $name "$@"
fi

実行 #! /bin/bash sh e.sh test_func 3 echo 'exit code1:'$? sh e.sh test_func 10 echo 'exit code2:'$? test -f $PWD/xx.txt echo 'exit code3:'$? test -f $PWD/e.sh echo 'exit code4:'$? コマンドを実行すると、次のような結果になります。

[root@ecs-centos-7 ~]# . /f.sh
終了コード1:6
終了コード2:5
終了コード3:1
終了コード4:0

スクリプト . /f.sh e.sh 関数は、引数が10に等しい場合、終了ステータスは5、それ以外は6となる

test_func コマンドは sh e.sh test_func 3 スクリプトを e.sh 関数では、入力される引数が3なので、終了ステータスは6、というようになります。 test_func コマンドの終了ステータスは 5

Linux では、コマンドの終了ステータスは、実行に成功した場合は 0、失敗した場合は 0 以外となります。

sh e.sh test_func 10 コマンドは、カレントディレクトリが存在するかどうかをチェックするものです test -f $PWD/xx.txt ファイルは、カレントディレクトリが存在しないので xx.txt というわけで、コマンドは失敗し、0 以外のステータスで終了します。

このため xx.txt はカレントディレクトリに存在するため e.sh コマンドは正常に実行され、終了ステータスは0です

$IFS

この変数は、文字列や単語の境界を識別するために Bash によって使用されます。デフォルト値はスペースで、スクリプトは必要に応じてこの変数の値を変更することができます。

既存の test -f $PWD/e.sh スクリプトで、次のように読みます。

b.sh

実行 #! /bin/bash va="a:b:c" vb="x-y-z" vc="e,f,g" IFS=""::" echo 'va:'$va echo 'vb:'$vb echo 'vc:'$vc echo IFS="-" echo 'va:'$va echo 'vb:'$vb echo 'vc:'$vc echo IFS="," echo 'va:'$va echo 'vb:'$vb echo 'vc:'$vc 結果は次のようになります。

[tt@ecs-centos-7 ~]$ . /b.sh
va:a b c
vb:x-y-z
vc:e,f,g

va:a:b:c
vb:x y z
vc:e,f,g

va:a:b:c
vb:x-y-z
vc:e f g

結果を見ればわかるように、このとき . /b.sh $IFS 文字列の場合 : としてパースされます。 "a:b:c"

いつ a b c $IFS 文字列の場合 - としてパースされます。 "x-y-z"

いつ x y z $IFS 文字列の場合 , としてパースされます。 "e,f,g"

home、$user、$uid、$groups。

e f g

HOME: user home directory
USER: Current user name
UID: current user ID
GROUPS: current user group ID

ホストタイプ、$mactype、$ostype

これらの変数は、すべてシステムのハードウェアを表します。

[tt@ecs-centos-7 ~]$ echo $HOME
/home/tt
[tt@ecs-centos-7 ~]$ echo $USER
tt
[tt@ecs-centos-7 ~]$ echo $UID
1003
[tt@ecs-centos-7 ~]$ echo $GROUPS
1003

概要

この記事では、一般的に使用される Bash の組み込み変数を紹介します。遠隔地やめったに使用されない変数については、関連資料を参照してください。

以上、シェルスクリプトで使用する組み込み変数(Bash組み込み変数)について詳しく説明しましたが、シェルの組み込み変数については、スクリプトハウスの他の関連記事にもご注目ください!(※)。