Loose-Info.com
Last Update 2022/07/20
TOP - 各種テスト - bash - シェル変数

シェル変数


(01) BASH

bashのインスタンスを呼び出すために使用される完全なファイル名に展開

(02) BASHPID

現在のbashプロセスのプロセスIDに展開

(03) BASH_REMATCH

[[ 式 ]] 内の=~演算子のマッチング結果が割り当てられる配列変数

(04) BASH_SUBSHELL

サブシェルまたはサブシェル環境の作成に伴い1つずつ増加

(05) BASH_VERSINFO

現在実行中のbashのバージョン情報を格納する読み取り専用の配列変数

(06) BASH_VERSION

現在実行中のbashのバージョン情報を表す文字列に展開

(07) EPOCHREALTIME

Unix Epoch (UTCでの1970年1月1日午前0時0分0秒) からの秒数をマイクロ秒単位の浮動小数点数として展開

(08) EPOCHSECONDSE

Unix Epoch (UTCでの1970年1月1日午前0時0分0秒) からの秒数として展開

(09) 欠番


(10) FUNCNAME

現在コールスタックにある全シェル関数の名前が入った配列変数

(11) GROUPS

現在のユーザーがメンバーであるグループのリストを含む配列変数

(12) HISTCMD

現在のコマンドのヒストリーリスト内のインデックス

(13) HOSTNAME

現在のホスト名

(14) HOSTTYPE

bashが実行されているマシンの種類を一意に表す文字列を自動的に設定

(15) LINENO

この変数が参照される度に、スクリプトまたは関数内の現在の行番号(1〜)を表す10進数に置換

(16) MACHTYPE

GNU標準の cpu-company-system 形式で、bashが実行されているシステムタイプを完全に説明する文字列を自動的に設定

(17) MAPFILE

組み込みコマンドmapfileが、変数名が与えられていない時に、読み込むテキストを保持するために作成される配列変数

(18) OLDPWD

cdコマンドでセットされた1つ前の作業ディレクトリ

(19) OPTARG

組み込みコマンドgetoptsで処理される最後(現在処理中)のオプション引数の値

(20) OPTIND

組み込みコマンドgetoptsで処理される次の引数のインデックス

(21) OSTYPE

bashが実行されているオペレーティングシステムを表す文字列が自動的に設定される

(22) PIPESTATUS

最も最近実行されたフォアグラウンドパイプラインの終了ステータス値のリストを含む配列変数

(23) PPID

シェルの親プロセスのプロセスID

(24) PWD

cdコマンドで設定された現在の作業ディレクトリ

(25) RANDOM

参照されるたびに、0から32767までのランダムな整数に展開
値の設定で乱数のシーケンスが初期化

(26) SECONDS

シェル起動からの秒数

(27) SHELLOPTS

有効になっているシェルオプションをコロンで区切ったリスト

(28) SHLVL

bashのインスタンスが開始される毎に1ずつ増加

(29) SRANDOM

参照されるたびに、32ビットの疑似乱数に展開

(30) UID

現在のユーザーのユーザーIDに展開

以下、シェルによって使用される変数の主なもの

(31) HOME

現在のユーザーのホームディレクトリ

(32) PATH

コマンドの検索パス

(33) SHELL

シェルへのフルパス名に展開

(34) TIMEFORMAT

「time」の接頭辞が付いたパイプラインの情報表示方法を指定するフォーマット文字列


(01) BASH


実行結果
$ echo $BASH /bin/bash <--- このbashのインスタンスを呼び出すために使用される完全なファイル名

(02) BASHPID


実行結果
$ echo $BASHPID 262 $ ps PID TTY TIME CMD 262 pts/0 00:00:00 bash <--- 現在のbashプロセスのプロセスID 308 pts/0 00:00:00 ps $ ( echo $BASHPID ; ps ) <--- サブシェル内でBASHPIDを出力 309 PID TTY TIME CMD 262 pts/0 00:00:00 bash 309 pts/0 00:00:00 bash <--- サブシェルのプロセスID 310 pts/0 00:00:00 ps

(03) BASH_REMATCH


sample3.sh
#!/bin/bash echo "例(1) [[ \$0 =~ .+\. ]]" if [[ $0 =~ .+\. ]]; then for (( i=0 ; i < ${#BASH_REMATCH[@]} ; ++i )) do echo "BASH_REMATCH[$(( i ))] = ${BASH_REMATCH[i]}" done fi echo echo "例(2) [[ \$0 =~ [a-z]+ ]]" if [[ $0 =~ [a-z]+ ]]; then for (( i=0 ; i < ${#BASH_REMATCH[@]} ; ++i )) do echo "BASH_REMATCH[$(( i ))] = ${BASH_REMATCH[i]}" done fi echo s="abc123def" echo "例(3) [[ \$s =~ ([a-z]+)[[:digit:]]+([a-z]+) ]]" if [[ $s =~ ([a-z]+)[[:digit:]]+([a-z]+) ]]; then for (( i=0 ; i < ${#BASH_REMATCH[@]} ; ++i )) do echo "BASH_REMATCH[$(( i ))] = ${BASH_REMATCH[i]}" done fi

実行結果
$ ./sample3.sh 例(1) [[ $0 =~ .+\. ]] BASH_REMATCH[0] = ./sample3. <--- インデックス0には正規表現全体にマッチした部分文字列を格納 例(2) [[ $0 =~ [a-z]+ ]] BASH_REMATCH[0] = sample 例(3) [[ $s =~ ([a-z]+)[[:digit:]]+([a-z]+) ]] BASH_REMATCH[0] = abc123def BASH_REMATCH[1] = abc <--- インデックス1には最初の( )内にマッチした部分文字列を格納 BASH_REMATCH[2] = def <--- インデックス2には2番目の( )内にマッチした部分文字列を格納

(04) BASH_SUBSHELL


sample4.sh
#!/bin/bash subshell() ( <--- 関数内は新規サブシェルで実行 echo "BASH_SUBSHELL = $BASH_SUBSHELL" ) echo "BASH_SUBSHELL = $BASH_SUBSHELL" echo subshell ; echo ( subshell ) ; echo <--- 以降、( )で新規サブシェルを生成 ( ( subshell ) ) ; echo ( ( subshell ) ; ( subshell ) ; subshell ) ; echo echo "BASH_SUBSHELL = $BASH_SUBSHELL"

実行結果
$ ./sample4.sh BASH_SUBSHELL = 0 BASH_SUBSHELL = 1 <--- subshell BASH_SUBSHELL = 2 <--- ( subshell ) BASH_SUBSHELL = 3 <--- ( ( subshell ) ) BASH_SUBSHELL = 3 <--- ( ( subshell ) ; ( subshell ) ; subshell ) BASH_SUBSHELL = 3 BASH_SUBSHELL = 2 BASH_SUBSHELL = 0

(05) BASH_VERSINFO


sample5.sh
#!/bin/bash echo "配列要素数 : ${#BASH_VERSINFO[@]}" echo echo "BASH_VERSINFO[0] : メジャーバージョン番号" echo "---> ${BASH_VERSINFO[0]}" echo echo "BASH_VERSINFO[1] : マイナーバージョン番号" echo "---> ${BASH_VERSINFO[1]}" echo echo "BASH_VERSINFO[2] : パッチレベル" echo "---> ${BASH_VERSINFO[2]}" echo echo "BASH_VERSINFO[3] : ビルドバージョン" echo "---> ${BASH_VERSINFO[3]}" echo echo "BASH_VERSINFO[4] : リリースステータス" echo "---> ${BASH_VERSINFO[4]}" echo echo "BASH_VERSINFO[5] : MACHTYPEの値" echo "---> ${BASH_VERSINFO[5]}" echo

実行結果
$ ./sample5.sh 配列要素数 : 6 BASH_VERSINFO[0] : メジャーバージョン番号 ---> 5 BASH_VERSINFO[1] : マイナーバージョン番号 ---> 1 BASH_VERSINFO[2] : パッチレベル ---> 16 BASH_VERSINFO[3] : ビルドバージョン ---> 1 BASH_VERSINFO[4] : リリースステータス ---> release BASH_VERSINFO[5] : MACHTYPEの値 ---> x86_64-pc-linux-gnu

(06) BASH_VERSION


実行結果
$ echo ${BASH_VERSINFO[@]} 5 1 16 1 release x86_64-pc-linux-gnu <--- BASH_VERSINFOに格納されている情報 $ echo $BASH_VERSION 5.1.16(1)-release <--- BASH_VERSINFOのMACHTYPEの値を除く情報を出力

(07) EPOCHREALTIME


実行結果
$ echo $EPOCHREALTIME 1656851905.911670 <--- Unix Epoch (UTCでの1970年1月1日午前0時0分0秒) からの秒数(マイクロ秒単位) $ date -u -d '@1656851905.911670' "+%F %T.%6N" 2022-07-03 12:38:25.911670 <--- EPOCHREALTIMEの値をdateコマンドでUTCにて出力 $ date -d '@1656851905.911670' "+%F %T.%6N" 2022-07-03 21:38:25.911670 <--- EPOCHREALTIMEの値をdateコマンドでローカル時刻にて出力

(08) EPOCHSECONDS


実行結果
$ echo $EPOCHSECONDS 1656852716 <--- Unix Epoch (UTCでの1970年1月1日午前0時0分0秒) からの秒数 $ date -u -d '@1656852716' Sun 3 Jul 12:51:56 UTC 2022 <--- EPOCHSECONDSの値をdateコマンドでUTCにて出力 $ date -d '@1656852716' Sun 3 Jul 21:51:56 JST 2022 <--- EPOCHSECONDSの値をdateコマンドでローカル時刻にて出力

(10) FUNCNAME


sample10.sh
#!/bin/bash func1() { echo "func1()内" echo "FUNCNAME要素数 : ${#FUNCNAME[@]}" echo "FUNCNAME要素 : ${FUNCNAME[@]}" echo echo "func1からfunc2を呼び出す" func2 } func2() { echo "func2()内" echo "FUNCNAME要素数 : ${#FUNCNAME[@]}" echo "FUNCNAME要素 : ${FUNCNAME[@]}" echo } echo "関数外" echo "FUNCNAME要素数 : ${#FUNCNAME[@]}" echo "FUNCNAME要素 : ${FUNCNAME[@]}" echo func1 func2 echo "関数外" echo "FUNCNAME要素数 : ${#FUNCNAME[@]}" echo "FUNCNAME要素 : ${FUNCNAME[@]}" echo

実行結果
$ ./sample10.sh 関数外 FUNCNAME要素数 : 0 <--- 関数未実行の場合は存在しない FUNCNAME要素 : func1()内 FUNCNAME要素数 : 2 FUNCNAME要素 : func1 main <--- インデックス0は実行中の関数。最後の要素はmain func1からfunc2を呼び出す func2()内 FUNCNAME要素数 : 3 FUNCNAME要素 : func2 func1 main func2()内 FUNCNAME要素数 : 2 FUNCNAME要素 : func2 main 関数外 FUNCNAME要素数 : 0 FUNCNAME要素 :

(11) GROUPS


実行結果
$ echo ${#GROUPS[@]} 2 <--- 配列要素数 $ echo ${GROUPS[@]} 1001 1002 <--- 配列要素リスト $ id uid=1001(testusr) gid=1001(testusr) groups=1001(testusr),1002(testgroup) <--- groupsと一致

(12) HISTCMD


実行結果
$ history -c <--- ヒストリーリストをクリア $ echo "1" 1 $ echo "2" 2 $ echo "3" 3 $ echo $HISTCMD 4 <--- この時点のインデックスは4 $ history 1 echo "1" 2 echo "2" 3 echo "3" 4 echo $HISTCMD <--- ヒストリーリストのインデックス4 5 history $ !4 <--- 4番目のコマンドラインを参照 echo $HISTCMD <--- ヒストリーリストのインデックス4のコマンドラインが実行される 6 <--- この時点のインデックスは6 $ history 1 echo "1" 2 echo "2" 3 echo "3" 4 echo $HISTCMD 5 history 6 echo $HISTCMD 7 history

(13) HOSTNAME


実行結果
$ echo $HOSTNAME test001 $ cat /etc/hostname test001 <--- 設定されるホスト名と一致

(14) HOSTTYPE


実行結果
$ echo $HOSTTYPE x86_64 <--- bashが実行されているマシンの種類を一意に表す文字列

(15) LINENO


sample15.sh (行番号付き出力)
1 #!/bin/bash 2 3 func1() 4 { 5 echo "func1() 1行目" 6 echo "func1() 2行目" 7 echo "$LINENO" 8 echo "func1() 4行目" 9 echo 10 } 11 12 func2() 13 { 14 echo "$LINENO" 15 echo "func2() 2行目" 16 echo 17 } 18 19 func1 20 echo "$LINENO" 21 func2 22 echo "$LINENO"

実行結果
$ ./sample15.sh func1() 1行目 func1() 2行目 7 <--- スクリプト先頭行からの行数 func1() 4行目 20 <--- 14 <--- func2() 2行目 22 <---

(16) MACHTYPE


実行結果
$ echo $MACHTYPE x86_64-pc-linux-gnu <--- GNU標準の cpu-company-system 形式で、bashが実行されているシステムタイプを完全に説明する文字列

(17) MAPFILE


sample16.txt
abc def ghi jkl mno

実行結果
$ mapfile < sample16.txt <--- mapfileコマンドで標準入力からテキストの読み込み $ echo ${#MAPFILE[@]} <--- 変数名指定が無いため配列変数MAPFILEに読み込まれる 5 <--- 読み込まれた要素数 $ echo ${MAPFILE[@]} abc def ghi jkl mno <--- 配列変数MAPFILEの要素

(18) OLDPWD


実行結果
$ pwd /home/testusr <--- 現在の作業ディレクトリ $ cd .. <--- cdコマンドで一つ上のディレクトリに移動 $ echo $OLDPWD /home/testusr <--- 一つ前の作業ディレクトリ $ cd testusr/ $ echo $OLDPWD /home $ cd /usr/ $ echo $OLDPWD /home/testusr $ cd /home/testusr/ $ echo $OLDPWD /usr $ cd /home/testusr/ <--- cdコマンドで現在の作業ディレクトリを指定 $ echo $OLDPWD /home/testusr <--- cdコマンドの指定が有効となりOLDPWDの値も現在の作業ディレクトリとなる $ pwd /home/testusr

(19) OPTARG


sample19.sh
#!/bin/bash while getopts "a:b:" c do case "$c" in a) echo "オプション -a" echo "オプション引数 : $OPTARG" ;; b) echo "オプション -b" echo "オプション引数 : $OPTARG" ;; esac done

実行結果
$ ./sample19.sh -a test1 -b test2 <--- サンプルスクリプトにオプションとオプション引数を付けて実行 オプション a オプション引数 : test1 <--- オプション a の引数 オプション b オプション引数 : test2 <--- オプション b の引数

(20) OPTIND


sample20.sh
#!/bin/bash echo "最初に処理する引数インデックス : $OPTIND" while getopts "abc" c do case "$c" in a) echo "オプション -a" echo "次に処理するインデックス : $OPTIND" ;; b) echo "オプション -b" echo "次に処理するインデックス : $OPTIND" ;; c) echo "オプション -c" echo "次に処理するインデックス : $OPTIND" ;; esac done

実行結果
$ ./sample20.sh -a -b -c <--- サンプルスクリプトにオプションを付けて実行 最初に処理する引数インデックス : 1 オプション -a 次に処理するインデックス : 2 オプション -b 次に処理するインデックス : 3 オプション -c 次に処理するインデックス : 4

(21) OSTYPE


実行結果
$ echo $OSTYPE linux-gnu <--- bashが実行されているオペレーティングシステムを表す文字列

(22) PIPESTATUS


sample22_1.c(実行ファイル sample22_1)
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { if (argc > 1) { /* 引数有りの場合は、引数の値を標準出力へ */ printf("%d", atoi(argv[1])); } else { /* 引数有りの場合は、「1」を標準出力へ */ printf("1"); } /* 終了ステータスとして0を返す */ return 0; }

sample22_2.c(実行ファイル sample22_2)
#include <stdio.h> int main(void) { int n; /* 標準入力から整数値を取得 */ scanf("%d", &n); /* 取得内容を終了ステータスとして返す */ return n; }

実行結果
$ ./sample22_1 | ./sample22_2 | ./sample22_1 2 | ./sample22_2 $ echo ${PIPESTATUS[@]} 0 1 0 2 <--- PIPESTATUS配列変数内に直前に実行されたパイプラインの各プロセスの終了ステータスを格納

(23) PPID


実行結果
$ ps PID TTY TIME CMD 301 pts/0 00:00:00 bash 323 pts/0 00:00:00 ps $ bash <--- 現在実行中のシェル「301」からシェルを起動 $ ps PID TTY TIME CMD 301 pts/0 00:00:00 bash 324 pts/0 00:00:00 bash <--- 追加となったプロセス(bash) 325 pts/0 00:00:00 ps $ echo $PPID 301 <--- 親プロセスのプロセスID(bash) $ bash <--- さらに現在実行中のシェル「324」からシェルを起動 $ ps PID TTY TIME CMD 301 pts/0 00:00:00 bash 324 pts/0 00:00:00 bash 326 pts/0 00:00:00 bash <--- 追加となったプロセス(bash) 327 pts/0 00:00:00 ps $ echo $PPID 324 <--- 親プロセスのプロセスID(bash)

(24) PWD


実行結果
$ echo $PWD /home/testusr <--- cdコマンドで設定された現在の作業ディレクトリ $ cd .. $ echo $PWD /home <--- 〃 $ cd /usr/local/ $ echo $PWD /usr/local <--- 〃 $ cd $ echo $PWD /home/testusr <--- 〃

(25) RANDOM


実行結果
$ echo $RANDOM 12449 <--- 参照する毎にランダムな整数に展開 $ echo $RANDOM 25972 <--- 〃 $ echo $RANDOM 1317 <--- 〃 $ echo $RANDOM 14819 <--- 〃 $ echo $RANDOM 1173 <--- 〃 $ RANDOM=1 <--- RANDOMを1に設定 $ echo $RANDOM 16807 $ echo $RANDOM 10791 $ echo $RANDOM 19566 $ RANDOM=1 <--- RANDOMを再度1に設定 $ echo $RANDOM 16807 <--- シード値が同じであれば以降の生成される乱数も同じ値となる $ echo $RANDOM 10791 $ echo $RANDOM 19566

(26) SECONDS


実行結果
$ date ; echo $SECONDS Tue 12 Jul 16:52:34 JST 2022 <--- 現在時刻 25 <--- シェル起動からの秒数 $ date ; echo $SECONDS Tue 12 Jul 16:52:39 JST 2022 30 $ date ; echo $SECONDS Tue 12 Jul 16:52:49 JST 2022 40 $ SECONDS=0 ; date <--- SECONDSを0に設定 Tue 12 Jul 16:53:21 JST 2022 <--- 0に設定した時刻 $ date ; echo $SECONDS Tue 12 Jul 16:53:29 JST 2022 <--- 0に設定後8秒経過 8 <--- SECONDSの値も8秒 $ date ; echo $SECONDS Tue 12 Jul 16:53:34 JST 2022 13 $ SECONDS=1000 ; date <--- SECONDSを1000に設定 Tue 12 Jul 17:00:44 JST 2022 <--- 1000に設定した時刻 $ date ; echo $SECONDS Tue 12 Jul 17:00:50 JST 2022 <--- 1000に設定後6秒経過 1006 <--- SECONDSの値は1000+6秒 $ date ; echo $SECONDS Tue 12 Jul 17:00:55 JST 2022 1011

(27) SHELLOPTS


実行結果
$ echo $SHELLOPTS braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor <--- 現在のシェルオプションリスト $ echo {肉,魚}{が,も}食べたい 肉が食べたい 肉も食べたい 魚が食べたい 魚も食べたい <--- ブレース展開が有効 $ set +o braceexpand <--- braceexpandオプションを無効化 $ echo $SHELLOPTS emacs:hashall:histexpand:history:interactive-comments:monitor <--- リストからbraceexpandが外れる $ echo {肉,魚}{が,も}食べたい {肉,魚}{が,も}食べたい <--- ブレース展開は無効 $ set -o braceexpand <--- braceexpandオプションを有効化 $ echo $SHELLOPTS braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor <--- リストにbraceexpandが戻る $ echo {肉,魚}{が,も}食べたい 肉が食べたい 肉も食べたい 魚が食べたい 魚も食べたい

(28) SHLVL


実行結果
$ echo $SHLVL 1 $ bash <--- bashインスタンスを開始 $ echo $SHLVL 2 <--- SHLVLが1増加 $ bash $ echo $SHLVL 3 $ exit exit <--- bashインスタンスを終了 $ echo $SHLVL 2 <--- SHLVLが1減少 $ exit exit $ echo $SHLVL 1

(29) SRANDOM


実行結果
$ echo $SRANDOM <--- SRANDOMを参照 1941324080 <--- 32ビット疑似乱数 $ echo $SRANDOM 701470467 $ echo $SRANDOM 4246103850 $ SRANDOM=1 <--- SRANDOMに1を設定 $ echo $SRANDOM 3127740232 $ echo $SRANDOM 2730929198 $ SRANDOM=1 <--- 再度SRANDOMに1を設定 $ echo $SRANDOM 2985074723 <--- SRANDOMへの値の設定の効果は見られない $ echo $SRANDOM 1001031370

(30) UID


実行結果
$ echo $UID 1001 $ id uid=1001(testusr) gid=1001(testusr) groups=1001(testusr),1002(testgroup) <--- uidと一致

(31) HOME


実行結果
$ echo $HOME /home/testusr <--- 現在のユーザーのホームディレクトリ

(32) PATH


実行結果
$ echo $PATH /bin:/usr/bin <--- コマンドの検索パス

(33) SHELL


実行結果
$ echo $SHELL /bin/bash <--- シェルへのフルパス名

(34) TIMEFORMAT


実行結果(1)
$ unset TIMEFORMAT <--- TIMEFORMATが未設定の場合 $ time sleep 3 | echo $TIMEFORMAT <--- 未設定のため出力なし real 0m3.002s <--- 「\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS」が設定された場合と同じように表示 user 0m0.001s sys 0m0.000s

実行結果(2)
$ TIMEFORMAT=$'\n%R\n%U\n%S' $ time sleep 3 | echo $TIMEFORMAT %R %U %S 3.003 0.000 0.002 %R : 経過時間(秒) %U : ユーザーモードで使用されたCPU秒数 %S : システムモードで使用されたCPU秒数

実行結果(3)
$ TIMEFORMAT=$'\n%lR\n%lU\n%lS' $ time sleep 3 | echo $TIMEFORMAT %lR %lU %lS 0m3.002s <--- 「l」オプションにより長い形式で出力 0m0.001s 0m0.000s

実行結果(4)
$ TIMEFORMAT=$'\n%2R\n%2U\n%2S' $ time sleep 3 | echo $TIMEFORMAT %2R %2U %2S 3.00 <--- 小数点以下2桁 0.00 0.00

実行結果(5)
$ TIMEFORMAT=$'\n(%U + %S) / %R --- %P(%%)' $ time sleep 3 | echo $TIMEFORMAT (%U + %S) / %R --- %P(%%) (0.001 + 0.000) / 3.002 --- 0.04(%) %P : (%U + %S) / %R (%) %% : 「%」のリテラル

実行環境

GNU bash, version 5.1.16
GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1


コード例・出力内容中の表記

・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。