Bash Basics | Basicsトップページ | トップページ

パラメータ

パラメータに空文字列を含む何らかの値が代入されている場合、そのパラメータは設定(定義)されていると言います。
一度値が設定されたパラメータはunsetで削除するまで設定された状態となります。

  1. 変数
    変数は名前を識別子として持つパラメータです。
    変数は値と0個以上の属性を持ちます。属性declareコマンドで設定することができます。
  2. 位置パラメータ
    1以上の整数を識別子として持つパラメータでシェルが起動された時の引き数が代入されています。
    setコマンドを使って代入仕直すこともできますが代入文を使って値を代入することはできません。
    2桁以上の位置パラメータは整数部分を{}で囲む必要があります。
  3. 特殊パラメータ
    シェルで特別な意味を持つ参照のみの(値を代入することができない)以下の表に示す特殊パラメータがあります。
    識別子説明
    *位置パラメータがある場合には、空白文字で区切られた全ての位置パラメータに展開されます。
    ダブルクォートでクォートされている場合には、IFSの最初の文字で区切られた1つの単語として展開されます。
    IFSが設定されていない場合には、空白文字で区切られます。
    IFSが空文字列の場合には、展開される位置パラメータは連結された一連の文字列となります。
    @位置パラメータがある場合には、空白文字で区切られた全ての位置パラメータに展開されます。
    ダブルクォートでクォートされている場合には、全ての位置パラメータは別々の単語として展開され、"$1" "$2" ...と同じ意味となります。
    #位置パラメータの数を示す10進数の整数値に展開されます。
    ?フォアグラウンドで最後に実行されたコマンドまたはパイプライン終了ステータスに展開されます。
    -現在のシェルのオプションフラグに展開されます。
    $シェルのプロセスIDに展開されます。
    ()を使ったサブシェルの内部ではサブシェルのプロセスIDではなく、現在のシェルのプロセスIDに展開されます。
    !最後に実行されたバックグラウンドのコマンドのプロセスIDに展開されます。
    0シェルまたは、スクリプト名に展開されます。
    _シェルの起動時には実行するシェルまたは、スクリプト名が展開されます。
    シェルでコマンドを実行した後では、最後に実行したコマンドの最後の展開後の引き数に展開されます。


変数

変数は名前を識別子として持つパラメータです。
変数は値と0個以上の属性を持ちます。属性declareコマンドで設定することができます。
bashでは、以下の3つの変数を利用することができます。

  1. 基本的な変数

    変数名: str1

    値: "Hello World"

    ${str1}

    変数名: str2

    値: "Hello Everyone"

    ${str2}

    変数名: i

    値: 256

    ${i}

    変数名: j

    値: 381

    ${j}

    • 固有の名前で識別可能な変数名を持ちます。
    • 0個以上の属性を持ちます。
    • 空文字列を含む値を持ちます。
  2. 配列変数(一次元の配列変数)

    変数名: var

    キー: 0

    値: 135

    ${var[0]}

    ${var[-n-1]}

    キー: 1

    値: 267

    ${var[1]}

    ${var[-n]}

    キー: 2

    値: 356

    ${var[2]}

    ${var[-n+1]}

    キー: n

    値: 181

    ${var[n]}

    ${var[-1]}

    • 固有の名前で識別可能な変数名と要素を示す整数(算術式を含む)のキー(添字、インデックス)を持ちます。
      キーは0から始まりますが、負の値の場合、最大のキーからのオフセットとなり、-1のキーは最後の要素を示します。
    • 0個以上の属性を持ちます。(型を含む属性はすべての要素で同じです。)
    • それぞれの要素ごとに空文字列を含む値を持ちます。
  3. 連想配列変数

    変数名: emp

    キー: "fistname"

    値: "Ichiro"

    ${emp["firstname"]}

    キー: "lastname"

    値: "Suzuki"

    ${emp["lastname"]}

    キー: "id"

    値: 874061

    ${emp["id"]}

    キー: "section"

    値: "Sales"

    ${emp["section"]}

    • 固有の名前で識別可能な変数名と要素を示す任意の文字列のキーを持ちます。
    • 0個以上の属性を持ちます。(型以外の属性はすべての要素で同じです。)
    • それぞれの要素ごとに空文字列を含む値を持ちます。

変数の宣言、属性の定義

bashで変数を使用するためには、変数名に値を設定するか、変数を宣言して属性を付与します。

宣言、属性の定義 説明、例
declare 変数名= 変数名を名前として持つ変数を明示的に宣言し、値を設定します。
declare score=75
$ declare temp
declare 変数名 変数名を名前として持つ変数を明示的に宣言します。
declare score=75
$ declare temp
declare -x 変数名=
または
export 変数名=
変数名を名前として持つ環境変数を明示的に宣言し、値を設定します。
declare -x temp=12
$ export score=75
declare -x 変数名
または
export 変数名
変数名を名前として持つ変数環境変数としての属性を付与します。
declare -x temp
$ export score
declare -r 変数名=
または
readonly 変数名=
変数名を名前として持つ読み込み専用の変数を明示的に宣言し、値を設定します。
読み込み専用属性を持つ変数の値を変更したり、変数を削除することはできません。
declare -r temp=12
$ readonly score=75
declare -r 変数名
または
readonly 変数名
変数名を名前として持つ変数に読み込み専用属性を付与します。
読み込み専用属性を持つ変数の値を変更したり、変数を削除することはできません。
declare -r temp
$ readonly score
変数名=(値1 値2 ... 値N) 変数名を名前として持つ配列変数"に値を設定します。
$ colors=(red blue green orange)
declare -a 変数名=(値1 値2 ... 値N) 変数名を名前として持つ配列変数"を明示的に宣言し、値を設定します。
declare -a colors=(red blue green orange)
declare -a 変数名 変数名を名前として持つ配列変数"を明示的に宣言します。
declare -a colors
declare -A 変数名=(["キー1"]=値1 ["キー2"]=値2 ... ["キーN"]=値N) 変数名を名前として持つ連想配列変数を明示的に宣言し、値を設定します。
declare -A colors=(["gray"]="#808080" ["blue"]="#0000ff")
declare -A 変数名 変数名を名前として持つ連想配列変数を明示的に宣言します。
declare -A colors
declare -i 変数名= 変数名を名前として持つ整数属性の変数(整数型変数)を明示的に宣言し、値を設定します。
declare -i length=110
declare -i 変数名 変数名を名前として持つ整数属性の変数(整数型変数)を明示的に宣言します。
declare -i length
declare -l 変数名= 変数名を名前として持つ文字列型変数を明示的に宣言し、値を設定します。
変数の値は英小文字に変換されます。
declare -l str="Hello World"
declare -l 変数名 変数名を名前として持つ文字列型変数を明示的に宣言します。
変数の値は英小文字に変換されます。
declare -l str
declare -u 変数名= 変数名を名前として持つ文字列型変数を明示的に宣言し、値を設定します。
変数の値は英大文字に変換されます。
declare -l str="Hello World"
declare -u 変数名 変数名を名前として持つ文字列型変数を明示的に宣言します。
変数の値は英大文字に変換されます。
declare -l str
※変数に値を設定する場合、変数名と=、=と値の間にはスペースを空けずに指定する必要があります。

変数への値の代入と展開

変数へ値を代入するには、変数名=のように空白を空けずに変数名と値を=で続けて記述します。
以下の構文で変数への値の代入、参照(展開)、定義済みの変数の削除を行うことができます。

基本的な変数配列変数連想配列変数
代入 変数名=

値を省略した場合、空文字列が代入されます。
複合代入構文によっ て値を配列に代入することができます。
変数名=(キー1=値1 キー2=値2 ... キーn=値n )

キーと値を=で続けて1組のペアとして任意の数だけ指定します。
値を省略した場合、空文字列が代入されます。
全体を()で囲みます。
一般的にはキーは0から始まる連続する整数で構成しますが、不連続な整数をキーに指定することも可能です。
キーは省略することができます。キーを省略した場合、その文中で直前に代入されたキーに1を加えた値と見做されます。
キーを省略することはできません。
事前に変数名が宣言されていない場合、代入を行うと新しい変数として設定されます。 未定義の連想配列変数への代入はできません。必ず事前に連想配列変数としての宣言が必要です。
配列の追加 変数名+=(キー1=値1 キー2=値2 ... キーn=値n )
現在の最大のキー値よりも1つ大きいキー値で新しい値が追加されます。 新しいキーと値の組が追加されます。
参照 $変数名、${変数名} ${変数名[キー]}
削除 unset 変数名とすると変数を削除することができます。 unset 変数名[キー]とすると指定されたキーの要素を削除することができます。
unset 変数名unset 変数名[*]、またはunset 変数名[@]とすると配列変数全体を削除することができます。
代入時、値はチルダ展開パラメータ展開コマンド置換算術式展開クォートの削除が行われます。
変数が整数属性を持つ(declare -iで宣言された)場合、算術式展開の「$(())」の展開を使わなくても値に対して算術式評価が行われます。
位置パラメータである"$@"を除いて単語の分割は行われません。また、パス名展開も行われません。 代入文は組み込みコマンドaliasdeclaretypesetexportreadonlylocalの引き数でも使用されます。

変数配列変数のキーに値を代入する時、+=演算子を使って直前の値に追加したり、加算することができます。
+=演算子を整数属性が設定された変数に対して使用すると、算術式評価が行われ、現在の値に加算されます。
+=演算子を文字列の値の変数に対して使用すると、値が展開されて現在の文字列の後ろに追加されます。

代入の例:
$ declare -i i x=3 y=4
$ i=x*y*2
$ i+=5
echo ${i}
29
$ str="Hello World"
$ str+=' !!'
$ echo ${str}
Hello World !!
$ colors=(red blue green orange)
$ colors+=(violet brown)
$ echo ${colors[@]}
red blue green orange violet brown
$ fruits=([0]=apple [2]=orange melon [5]=lemon)
$ echo ${!fruits[@]}
0 2 3 5
$ declare -A employee=([no]=3267 [fistname]="ichiro" [lastname]="suzuki")
$ echo ${employee[@]}
3267 suzuki ichiro

スコープと環境変数

デフォルトでは変数、および関数のスコープ(有効範囲)はその変数や関数を定義したシェルのプロセス内でのみ有効となります。
declareコマンドで-xオプションを指定するか、exportコマンドでエクスポートした場合には、シェルから起動するサブシェルやコマンド内、およびそれらからさらに起動される孫以降のプロセス全てで参照可能となります。
このようにエクスポートされて後続の環境全てで参照可能となった変数を環境変数と呼びます。
後続の環境(プロセス)での環境変数の値は親から起動された時点の値が引き継がれますが、子のプロセスでは別のスコープとして管理されます。このため、非同期に親子で値を変更してもそれらの値がお互いに影響を受けることはありません。
つまり、環境変数を使用して子から親へ値や状態を受け渡すことはできません。

また、属性もその属性を設定したシェルのプロセス内でのみ有効となります。読み込み専用属性が付加された環境変数は後続の環境では別のスコープとなり、読み込み専用属性は失われ、値を変更することができますが、変更された内容はそれ以降の環境のみで引き継がれ、読み込み専用属性が設定されている親の変数の値は変更されません。

  • シェル1
    declare -rx var="apple"
    • シェル2
      変数varの値はapple
      • シェル3
        シェル3が起動された時点では変数varの値はapple
        var="orange"を代入
        • シェル5
          変数varの値はorange
        • シェル6
          変数varの値はorange
      • シェル4
        変数varの値はapple
        • シェル7
          変数varの値はapple
        • シェル8
          変数varの値はapple
例えば、上記のようにシェル1でエクスポートされ、読み込み専用属性を付加された変数varはエクスポートされているため、後続のシェル2でも値はappleとして参照することができます。しかし、読み込み専用属性は失われています。
さらに後続のシェル3で値をorangeに変更すると、シェル3から起動されるシェル5とシェル6ではvarの値は変更されたorangeとなります。
シェル4とシェル4から起動されるシェル7とシェル8ではシェル1で設定された値appleとなります。

関数は現在のシェル内で実行されるため、関数内で行われた変数に対する全ての変更(定義、値の変更、削除)は関数を呼び出したシェルにも影響します。
localを使って関数内(とその関数から呼び出される後続の関数内に)に閉じた局所的なローカル変数を定義することが可能です。
関数が入れ子になっている場合は注意が必要です。
例えば、親、子、孫の3つの階層になっている関数の呼び出しで子の関数内でのみ、ローカル変数として定義されていた場合、呼び出された関数内(子)での変更は呼出元(親)に影響を与えることはありませんが関数内(子)でさらに別の関数(孫)を呼び出した場合、呼び出した先(孫)でも同様にローカル変数数として定義されていない限り、その変更は(子)に影響します。ただし、その変更が呼び出し元(親)に影響を与えることはありません。
つまり、関数におけるローカル変数は、単純に呼び出し元に影響を与えない、という以外にありません。
このため、関数の再利用を考えた場合、関数内で使用する全ての変数ローカル変数として定義することが望ましいです。

例として下記のようなスクリプトlocal.shを作成します。
#!/usr/bin/bash

function func1 () {
    local var1="Hello World"
    var2="Hello World"
    echo local var1: \"${var1}\" in func1
    echo var2: \"${var2}\" in func1
    echo
    func2
    echo var1: \"${var1}\" in func1 after calling func2
    echo var2: \"${var2}\" in func1 after calling func2
    echo
}
function func2 () {
    var1="Welcome to the World"
    var2="Welcome to the World"
    unset var3
    echo var1: \"${var1}\" in func2
    echo var2: \"${var2}\" in func2
    echo
}

var1="Hello"
var2="Hello"
var3="Hello"
echo var1: \"${var1}\" in main
echo var2: \"${var2}\" in main
echo var3: \"${var3}\" in main
echo

func1
echo var1: \"${var1}\" in main after calling func1
echo var2: \"${var2}\" in main after calling func1
echo var3: \"${var3}\" in main after calling func1

実行例:
$ ./local.sh 
var1: "Hello" in main
var2: "Hello" in main
var3: "Hello" in main

local var1: "Hello World" in func1
var2: "Hello World" in func1

var1: "Welcome to the World" in func2
var2: "Welcome to the World" in func2

var1: "Welcome to the World" in func1 after calling func2
var2: "Welcome to the World" in func1 after calling func2

var1: "Hello" in main after calling func1
var2: "Welcome to the World" in main after calling func1
var3: "" in main after calling func1
  1. スクリプト内でvar1, var2, var3に"Hello"を初期値として代入します。
  2. 関数func1を呼び出します。
  3. func1の内部で同名のvar1をローカル変数として定義し、"Hello World"を代入します。
  4. var2へ、"Hello World"を代入します。
  5. 関数func2を呼び出します。
  6. func2の内部でvar1へ、"Welcome to the World"を代入し、var2へ、"Welcome to the World"を代入します。
  7. var3を削除(unset)します。
  8. func1で再びvar1, var2の値を参照するとどちらもfunc2で代入された内容に書き変わっています。
    ローカル変数であっても呼び出した先の関数で変更が行われると影響を受けます。
  9. スクリプトのmain(関数の外側、呼び出した後)で再びvar1の値を参照するとfunc1でローカル変数として定義されていたため、変更の影響を受けていないことが確認できます。一方でvar2はfunc1, func2で変更された内容に書き変わっています。同様にvar3はfunc2内で削除されたため、未定義となっています。


位置パラメータ

位置パラメータは1以上の整数値で表されるパラメータでシェルが起動された時の引き数が代入されます。
setを使って位置パラメータに代入し直すことも可能ですが、代入文を使っての値の代入はできません。
シェルの関数が呼び出された場合、関数内で位置パラメータを参照すると関数を呼び出した時の引き数が代入されています。関数の処理から呼び出し元に戻った場合、呼び出し元で設定されていた位置パラメータの内容のままとなります。
2桁以上の整数値で表される位置パラメータを展開する場合、整数値を{}で囲む必要があります。

位置パラメータ説明
${1}
または
$1
シェルへの一番目の引き数が展開されます。
関数内では関数への一番目の引き数が展開されます。
${2}
または
$2
シェルへの二番目の引き数が展開されます。
関数内では関数への二番目の引き数が展開されます。
${n}
または
$n
シェルへのn番目の引き数が展開されます。
関数内では関数へのn番目の引き数が展開されます。
nが2桁以上の整数値の場合、${n}のようにnを{}で囲む必要があります。

例として下記のようなスクリプトparams.shを作成します。
#!/usr/bin/bash

for ((i=1; i<=$#; i++)) {
    eval echo '\$'$i: \$$(($i))
}
実行例:
$ ./params.sh a b c
$1: a
$2: b
$3: c
$ ./params.sh "a b c" 1 2
$1: a b c
$2: 1
$3: 2


特殊パラメータ

シェルは特殊文字で表されるいくつかの特別なパラメータがあります。
下記の特殊パラメータは参照のみ(読み込み専用)で値を代入することはできません。

特殊パラメータ説明
${*}
または
$*
全ての位置パラメータに展開されます。
ダブルクォートに囲まれた中で展開される時は、IFSの最初の文字で区切られた1つの単語として展開されます。
つまり、"$*"は"$1c$2c...c$n"に展開されます。cはIFSの最初の文字となります。
IFSが設定されていない場合、cは空白文字となり、空白文字で区切られた1つの単語となります。
IFSが空文字列の場合、全ての位置パラメータは区切られず、連結された1つの単語となります。
${@}
または
$@
全ての位置パラメータに展開されます。
ダブルクォートに囲まれた中で展開される時は、それぞれ別々の単語として展開されます。
つまり、"$@"は"$1" "$2" ... "$n"に展開されます。
位置パラメータがない場合、"$@"、および$@を展開すると取り除かれます。
${#}
または
$#
位置パラメータの個数を示す整数値に展開されます。
${?}
または
$?
最後に実行されたフォアグラウンドのパイプライン終了ステータスに展開されます。
${-}
または
$-
現在のシェルで有効化されているオプションのうち、setで指定可能な引き数「abefhkmnptuvxBCEHPT」に展開されます。
オプションオプション名
aallexport
bnotify
eerrexit
fnoglob
hhashall
kkeyword
mmonitor
nnoexec
pprivileged
tonecmd
unounset
vverbose
xxtrace
Bbraceexpand
Cnoclobber
Eerrtrace
Hhistexpand
Pphysical
Tfunctrace
${$}
または
$$
現在のシェルのプロセスIDに展開されます。
${!}
または
$!
最後にバックグラウンドで実効されたコマンドのプロセスIDに展開されます。
${0}
または
$0
現在のシェルまたはスクリプトの名前に展開されます。
コマンドを記述したスクリプトを指定してbashを起動した場合、$0にはスクリプトのファイル名が設定されます。
bashを起動する際に-cオプションと複数の文字列を指定した場合、最初の文字列がコマンドとして解釈され、2つ目の文字列が$0に設定されます。
$ bash -c 'echo $0' TestCommand
TestCommand
実行例についての説明はシェルのオプション-cを参照してください。
${_}
または
$_
シェルの起動時には実行するシェルまたはスクリプトの絶対パスが設定されます。
シェルの起動後にコマンドを実効している場合、最後(直前)に実行したコマンドに対する展開後の最後の引き数が設定されます。
$*$@の違いについて、下記のスクリプトparam.shを作成して確認します。
#!/usr/bin/bash

function print() {
    for ((i=1; i<=$#; i++)) {
        eval echo '\$'$i: \$$(($i))
    }
}

echo 'Case: IFS=;'
IFS=';'
echo '$*': "\"$*\""
echo '$@': "\"$@\""
echo 'Sub Case: "$*"'
print "$*"
echo 'Sub Case: "$@"'
print "$@"

echo 'Case: IFS='
IFS=''
echo '$*': "\"$*\""
echo '$@': "\"$@\""
echo 'Sub Case: "$*"'
print "$*"
echo 'Sub Case: "$@"'
print "$@"
実行例:
$ ./param.sh 
Case: IFS=;
$*: ""
$@: ""
Sub Case: "$*"
$1:
Sub Case: "$@"
Case: IFS=
$*: ""
$@: ""
Sub Case: "$*"
$1:
Sub Case: "$@"
位置パラメータがない場合、"$*"は関数へ空文字列が渡されていますが、"$@"は関数へは引き数が渡されません。
"$@"を使用する場合、構文上で何も無くなることが許されないような場所での記述には注意が必要です。
例えば、[ "$@" == "" ]のような記述をした場合、位置パラメータがないと構文エラーとなります。
これは、[ "" == "" ]ではなく、[ == "" ]と展開されるからです。
$ ./param.sh a b c
Case: IFS=;
$*: "a;b;c"
$@: "a b c"
Sub Case: "$*"
$1: a b c
Sub Case: "$@"
$1: a
$2: b
$3: c
Case: IFS=
$*: "abc"
$@: "a b c"
Sub Case: "$*"
$1: abc
Sub Case: "$@"
$1: a
$2: b
$3: c
複数の位置パラメータがある場合、"$*"はIFSの最初の文字で区切られた1つの単語(引き数)として関数へ渡されていますが、"$@"はそれぞれ別々の単語(引き数)として関数へ渡されています。
IFSが空文字列の場合、"$*"は引き数が連結されて1つの単語(引き数)として関数へ渡されます。
$ ./param.sh a b c "d e f" "g h"
Case: IFS=;
$*: "a;b;c;d e f;g h"
$@: "a b c d e f g h"
Sub Case: "$*"
$1: a b c d e f g h
Sub Case: "$@"
$1: a
$2: b
$3: c
$4: d e f
$5: g h
Case: IFS=
$*: "abcd e fg h"
$@: "a b c d e f g h"
Sub Case: "$*"
$1: abcd e fg h
Sub Case: "$@"
$1: a
$2: b
$3: c
$4: d e f
$5: g h
上記の例と同様ですが、"$@"はクォーテーションで囲まれた空白文字を含む文字列が渡されても1つの引き数として処理されます。
$ ./param.sh a b c "" d
Case: IFS=;
$*: "a;b;c;;d"
$@: "a b c  d"
Sub Case: "$*"
$1: a b c  d
Sub Case: "$@"
$1: a
$2: b
$3: c
$4:
$5: d
Case: IFS=
$*: "abcd"
$@: "a b c  d"
Sub Case: "$*"
$1: abcd
Sub Case: "$@"
$1: a
$2: b
$3: c
$4:
$5: d
空文字列を引き数とした場合も同様に"$@"は1つの引き数として処理されます。


シェル変数

以下の変数はシェルが設定します。

シェル変数名説明
BASH現在実行しているbashの完全なパスが設定されます。
BASHOPTS有効化されているシェルのオプションshoptでonになっているもの)がコロンで区切って設定されます。
このシェル変数は読み込み専用です。
このシェル変数がbashの起動時に設定されている場合、設定ファイルを読み込む前にシェル変数で設定されているオプションが有効化されます。
BASHPID現在実行しているbashのプロセスIDが設定されます。
サブシェルなどいくつかの環境では$$と値が異なります。
BASH_ALIASES設定されているエイリアスに対応する連想配列です。
$ for aliase in "${!BASH_ALIASES[@]}"; do echo "${aliase}=${BASH_ALIASES[${aliase}]}"; done
grep=grep --color=auto
egrep=egrep --color=auto
fgrep=fgrep --color=auto
cp=cp -i
mv=mv -i
rm=rm -i
..=cd ..
which=alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde
la=ls -aF
ls=ls -NF --show-control-chars
ll=ls -l
l.=ls -d .* --color=auto
vi=vim
エイリアスはaliasコマンドで編集しますが、この配列変数"を編集するとエイリアスを変更することができます。
つまり、配列変数"に要素を追加するとエイリアスに追加され、配列変数"の要素を削除するとエイリアスが削除されます。
BASH_ARGC拡張デバッグモード(shoptextdebugオプションが有効)の場合、現在の呼び出しスタックのフレームごとの引き数の数が配列変数"に設定されます。
サブルーチンが実行されるたびにそのサブルーチンの引き数の数がスタックの一番上に置かれます。
例はトレース情報の出力と記録を参照してください。
BASH_ARGV拡張デバッグモード(shoptextdebugオプションが有効)の場合、現在の呼び出しスタックのフレームごとの全ての引き数が配列変数"に設定されます。
サブルーチンが実行されるたびにそのサブルーチンの引き数がスタックの一番上に置かれます。
例はトレース情報の出力と記録を参照してください。
BASH_CMDSbashが内部に持つコマンドのハッシュテーブルに対応する連想配列です。
ハッシュテーブルはhashコマンドで編集しますが、この配列変数"を編集するとハッシュテーブルを変更することができます。
つまり、配列変数"に要素を追加するとハッシュテーブルに追加され、配列変数"の要素を削除するとハッシュテーブルから削除されます。
BASH_COMMAND現在実行しているか実行しようとしているコマンドが設定されます。
シグナルを受信しtrapによってシェルがコマンドを実行している場合は、trapをトリガーした時に実行していたコマンドが設定されます。
BASH_EXECUTION_STRINGbashの起動時のオプション-cで指定されたコマンドが設定されます。
BASH_LINENO現在実行中のシェル(スクリプトファイル)内で関数が呼び出された場合、関数を呼び出した行数がスタック状に配列変数"に設定されます。
配列変数"の最初の要素の${BASH_LINENO[0]}は現在実行中の関数が呼び出された(呼び出し元の)行数が設定され、添字が1つずつ増えるごとに呼び出し元に遡って、呼び出された行数が設定されます。
ある関数${FUNCNAME[$i+1]}から関数${FUNCNAME[$i]}を呼び出した場合、${BASH_LINENO[$i]}には、呼び出し元の行数が設定されます。
現在の行数は${LINENO}に設定されます。
BASH_REMATCH組み込みコマンド[[中で二項演算子 =~ が使用されている場合、正規表現にマッチする文字列が配列変数"に設定されます。
配列変数"の最初の要素の${BASH_REMATCH[0]}には正規表現全体にマッチする文字列が設定されます。
配列変数"の要素nの${BASH_REMATCH[n]}には、()でグループ化された部分式のn番目にマッチする文字列が設定されます。
$ var=abcd12345ef678
$ [[ ${var} =~ ^([a-z]+)[0-9]+(.*)$ ]]
$ echo ${BASH_REMATCH[0]}
abcd12345ef678
$ echo ${BASH_REMATCH[1]}
abcd
$ echo ${BASH_REMATCH[2]}
def678
BASH_SOURCE組み込みコマンドsourceコマンドでファイルを読み込んで実行した場合、呼び出されたファイル名がスタック状に配列変数"に設定されます。
配列変数"の最初の要素の${BASH_SOURCE[0]}にはsourceコマンドで呼び出されて現在実行中のファイル名が設定されます。
配列変数"の要素nの${BASH_SOURCE[n]}には、sourceコマンドで階層的にファイルが読み込まれている場合、n番前に読み込まれたファイル名が設定されます。
BASH_SOURCELLシェルの起動時の初期値を0として、サブシェルが作成されるごとに1ずつ増加した値が設定されます。
BASH_VERSINFO読み込み専用属性を持つ配列変数"で、現在実行されているbashのバージョン情報が下記の通り設定されます。
配列変数"の要素 設定される値
${BASH_VERSINFO[0]} メジャーバージョン番号 4
${BASH_VERSINFO[1]} マイナーバージョン番号 2
${BASH_VERSINFO[2]} パッチレベル 46
${BASH_VERSINFO[3]} ビルド番号 2
${BASH_VERSINFO[4]} リリースステータス release
${BASH_VERSINFO[5]} ${MACHYPE}の値 x86_64-redhat-linux-gnu
BASH_VERSION現在実行されているbashのバージョン情報を示す文字列が設定されます。
$ echo ${BASH_VERSION}
4.2.46(2)-release
COMP_CWORDプログラム補完機能から呼ばれたシェル関数または外部コマンド内で現在カーソルがある位置の単語配列変数"${COMP_WORDS}の要素数が設定されます。
COMP_KEYプログラム補完機能から呼ばれたシェル関数または外部コマンド内で補完関数を呼び出したキーのコードが設定されます。
補完操作のキー値(10進数)
Tab9
Ctrl+I9
Esc Esc27
Esc+*42
Esc+?63
COMP_LINEプログラム補完機能から呼ばれたシェル関数または外部コマンド内で現在のコマンド行が設定されます。
COMP_POINTプログラム補完機能から呼ばれたシェル関数または外部コマンド内で現在のコマンド行の先頭からのカーソルの位置が設定されます。
現在のカーソルの位置がコマンド行の最期にある場合は${#COMP_LINE}の値と等しくなります。
COMP_TYPEプログラム補完機能から呼ばれたシェル関数または外部コマンド内で補完のタイプを示すコードが設定されます。
補完タイプ値(10進数)説明
Tab9通常の補完、TabまたはCtrl+Iによる補完
!33readlineのshow-all-if-ambiguousがonの場合の通常の補完
%37menu-completeによる補完
*42Esc+*による補完
?63連続したTab、連続したEsc、連続したCtrl+IまたはEsc+?の入力による補完
@64readlineのshow-all-if-unmodifiedがon(show-all-if-ambiguousはoff)の場合の通常の補完
COMP_WORDBREAKS単語補完を行う際、readlineが単語分割の区切り文字として扱う文字のリストです。
このシェル変数をunsetすると再びsetしても動作しません。
COMP_WORDSプログラム補完機能から呼ばれたシェル関数または外部コマンド内で現在のコマンド行を${COMP_WORDBREAKS}によって単語分割された各単語配列変数"です。
COPROC組み込みコマンドcoprocで明示的に名前を指定せずにコプロセスを実行した場合、コプロセスと接続されている標準入出力ファイルディスクリプタ配列変数"に設定されます。
配列変数"の要素説明
${COPROC[0]}コプロセス標準出力と接続されたファイルディスクリプタ
${COPROC[1]}コプロセス標準入力と接続されたファイルディスクリプタ

例はコプロセスとのパイプを参照してください。
DIRSTACK現在のディレクトリスタックの内容が配列変数"に設定されます。
ディレクトリスタックの追加と削除は組み込みコマンドpushdpopdで行います。
ディレクトリスタックの内容が変更される時、このシェル変数の値に~が含まれる場合、チルダ展開が行われます。
$ pushd www/html/
~/www/html ~
$ pushd ../js
~/www/js ~/www/html ~
$ pushd ../images/
~/www/images ~/www/js ~/www/html ~
$ dirs -v
 0  ~/www/images
 1  ~/www/js
 2  ~/www/html
 3  ~
$ echo ${DIRSTACK[@]}
~/www/images /home/user1/www/js /home/user1/www/html /home/user1
このシェル変数をunsetすると再びsetしても動作しません。
$ echo ${DIRSTACK[@]}
~/www/images /home/user1/www/js /home/user1/www/html /home/user1
$ unset DIRSTACK
$ echo ${DIRSTACK[@]}

$ dirs -v
 0  ~/www/images
 1  ~/www/js
 2  ~/www/html
 3  ~
$ pushd +2
~/www/html ~ ~/www/images ~/www/js
$ echo ${DIRSTACK[@]}

EUID現在のユーザーの実効ユーザーIDが設定されます。
このシェル変数は読み込み専用です。
FUNCNAME現在実行中のシェル(スクリプトファイル)内で関数が呼び出された場合、呼び出された関数名がスタック状に配列変数に設定されます。
配列変数の最初の要素の${FUNCNAME[0]}は現在実行中の関数名が設定され、添字が1つずつ増えるごとに呼び出し元に遡って、呼び出された関数名が設定されます。
最も下の要素(配列変数の最も大きな添字の要素)はそのシェルがsourceコマンドから実行された場合、"source"が設定され、それ以外の場合には"main"が設定されます。

例として下記のようなスクリプトfuncname.shを作成します。
#!/usr/bin/bash

# エラー発生時のトラップを設定
set -o errtrace
trap catch ERR
trap finally EXIT

# Sub Function A
function func_A () {
    # func_A:11 is called from main:57
    echo ${FUNCNAME[0]}:${LINENO} is called from ${FUNCNAME[1]}:${BASH_LINENO[0]}
    func_B
    return 0
}

# Sub Function B
function func_B () {
    # func_B:19 is called from func_A:12
    echo ${FUNCNAME[0]}:${LINENO} is called from ${FUNCNAME[1]}:${BASH_LINENO[0]}
    func_C
    return 0
}

# Sub Function C
function func_C () {
    # func_C:27 is called from func_B:20
    echo ${FUNCNAME[0]}:${LINENO} is called from ${FUNCNAME[1]}:${BASH_LINENO[0]}

    # エラーを発生させる(実行するコマンド"cmdcmd"が存在しない)
    cmdcmd
    return 0
}

function catch () {
    # スタックトレースの表示
    echo "##### Stack Trace #####" 1>&2
    for ((i=0; i<${#BASH_LINENO[*]}; i++))
    do
    if [ $i == 0 ];
    then
        echo $((${#BASH_LINENO[*]}-$i)): ${BASH_SOURCE[$i]}: \
		     ${FUNCNAME[$i]}: "Current" 1>&2
    else
        echo $((${#BASH_LINENO[*]}-$i)): ${BASH_SOURCE[$i]}: \
		     ${FUNCNAME[$i]}: ${BASH_LINENO[$(($i-1))]} 1>&2
    fi
    done
    return 0
}

function finally () {
    # 終了処理を記述
    echo "Exiting at ${FUNCNAME[1]}"
}

# メインの処理
func_A
echo '#### end ####'
実行例:
$ sh ./funcname.sh
func_A:11 is called from main:55
func_B:19 is called from func_A:12
func_C:27 is called from func_B:20
./funcname.sh: 行 30: cmdcmd: コマンドが見つかりません
##### Stack Trace #####
5: ./funcname.sh: catch: Current
4: ./funcname.sh: func_C: 30
3: ./funcname.sh: func_B: 20
2: ./funcname.sh: func_A: 12
1: ./funcname.sh: main: 55
#### end ####
Exiting at main
  1. スクリプト"funcname.sh"を実行します。
  2. メインの処理として定義された関数"func_A"を呼び出します。
  3. 実行中の関数名"func_A"と実行中の行数"11"と呼び出し元の関数名"main"と呼び出された行数"55"を出力します。
  4. 定義された関数"func_B"を呼び出します。
  5. 実行中の関数名"func_B"と実行中の行数"19"と呼び出し元の関数名"func_A"と呼び出された行数"12"を出力します。
  6. 定義された関数"func_C"を呼び出します。
  7. 実行中の関数名"func_C"と実行中の行数"27"と呼び出し元の関数名"func_B"と呼び出された行数"20"を出力します。
  8. 30行目のコマンド"cmdcmd"は存在しないためエラーが発生します。
  9. あらかじめtrapコマンドでエラーが発生した場合の処理としてcatch関数を定義しているため、catch関数が呼び出されます。
  10. 呼び出された関数と行数のスタックトレースを出力します。
  11. スクリプトの実行終了とともにシェルのプロセスを終了(exit)するため、終了処理として定義されたfinally関数が実行され、メッセージ"Exiting at main"を出力します。
    もし、スクリプト中でset -eが実行され、エラー発生時に終了するように設定されていた場合、エラー発生時の実行中の関数名(この場合はmainではなく、func_C)が終了時の関数として出力されます。

sourceコマンドによる実行例:
$ source ./funcname.sh
func_A:11 is called from source:55
func_B:19 is called from func_A:12
func_C:27 is called from func_B:20
./funcname.sh: 行 30: cmdcmd: コマンドが見つかりません
##### Stack Trace #####
5: ./funcname.sh: catch: Current
4: ./funcname.sh: func_C: 30
3: ./funcname.sh: func_B: 20
2: ./funcname.sh: func_A: 12
1: ./funcname.sh: source: 55
#### end ####
  1. sourceコマンドでスクリプト"funcname.sh"を実行します。
  2. メインの処理として定義された関数"func_A"を呼び出します。
  3. 実行中の関数名"func_A"と実行中の行数"11"と呼び出し元の関数名"source"と呼び出された行数"55"を出力します。
  4. 定義された関数"func_B"を呼び出します。
  5. 実行中の関数名"func_B"と実行中の行数"19"と呼び出し元の関数名"func_A"と呼び出された行数"12"を出力します。
  6. 定義された関数"func_C"を呼び出します。
  7. 実行中の関数名"func_C"と実行中の行数"27"と呼び出し元の関数名"func_B"と呼び出された行数"20"を出力します。
  8. 30行目のコマンド"cmdcmd"は存在しないためエラーが発生します。
  9. あらかじめtrapコマンドでエラーが発生した場合の処理としてcatch関数を定義しているため、catch関数が呼び出されます。
  10. 呼び出された関数と行数のスタックトレースを出力します。
  11. sourceコマンドでスクリプトが現在のシェル内で実行されているため、実行中のシェル(現在のシェル)は継続中のため、終了のメッセージは出力されません。
    もし、スクリプト中でset -eが実行され、エラー発生時に終了するように設定されていた場合、エラー発生時の実行中の関数名(この場合はmainではなく、func_C)が終了時の関数として出力した後、現在のシェルそのものを終了させます。
GROUPS現在のユーザーが所属する全てのグループのIDが配列変数"に設定されます。
このシェル変数への代入は終了ステータスとしてエラーを返します。
このシェル変数をunsetすると再びsetしても動作しません。
HISTCMDコマンドの履歴リストにおける次の履歴番号(次に実行するコマンドに割り振られる履歴番号)が設定されます。
このシェル変数をunsetすると再びsetしても動作しません。
HOSTNAME現在のシェルが実行されているホスト名が設定されます。
HOSTTYPE現在のシェルが実行されているホストの種類を示す文字列が設定されます。
LINENOスクリプトファイルや関数内でこのシェル変数を参照した行番号を表す10進数が設定されます。
対話型のシェルなどスクリプトファイルや関数内ではない場合にこのシェル変数を参照すると不定な値が返されます。
このシェル変数をunsetすると再びsetしても動作しません。
MACHTYPE現在のシェルが実行されているホストの種類を示す完全な文字列(GNU標準のcpu-company-systemの形式の文字列)が設定されます。
MAPFILE組み込みコマンドmapfileに変数名が明示的に指定されなかった場合、読み込んだテキストが配列変数"に設定されます。
OLDPWD1つ前の作業ディレクトリが設定されます。
OPTARG組み込みコマンドgetoptsで処理した最後のオプションの引き数が設定されます。
例はオプションのチェックを参照してください。
OPTIND組み込みコマンドgetoptsで次に処理するオプション、引き数のインデックス(位置パラメータの位置)が設定されます。
例はオプションのチェックを参照してください。
OSTYPE現在のシェルが実行されているオペレーティングシステムを示す文字列が設定されます。
PIPESTATUSフォアグラウンドで最後に実行したパイプラインの各プロセスの終了ステータスが配列変数"に設定されます。
$ true | true | false | false | true
$ echo ${PIPESTATUS[@]}
0 0 1 1 0
PPID現在のシェルの親プロセスのIDが設定されます。
このシェル変数は読み込み専用です。
PWD現在の作業ディレクトリ(カレントディレクトリ)が設定されます。
RANDOMこのシェル変数を参照するたびに、0から32767までのランダムな整数値が設定されます。
値を代入すると乱数の列を初期化することができます。
このシェル変数をunsetすると再びsetしても動作しません。
READLINE_LINE組み込みコマンドの"bind -x"で使用するreadlineの編集バッファの内容が設定されます。
READLINE_POINT組み込みコマンドの"bind -x"で使用するreadlineの編集バッファの挿入位置が設定されます。
REPLY組み込みコマンドreadで引き数が指定されなかった場合、およびselectで読み込まれた行が設定されます。
SECONDS現在のシェルが起動されてからの経過秒数が設定されます。
値を代入すると代入した値とそれ以降の経過秒数が設定されます。
このシェル変数をunsetすると再びsetしても動作しません。
SHELLOPTS有効化されているシェルのオプションsetの-oオプションの有効な引き数)がコロンで区切って設定されます。
このシェル変数は読み込み専用です。
このシェル変数がbashの起動時に設定されている場合、設定ファイルを読み込む前にシェル変数で設定されているオプションが有効化されます。
SHLVLbashが起動する時に設定されている値をインクリメント(1増加)させた値が設定されます。
UID現在のシェルを起動した時のシェルのユーザーユーザーIDが設定されます。
このシェル変数は読み込み専用です。

以下の変数はシェルが使用します。bashがデフォルト値を設定することもあります。
シェル変数名説明
BASH_ENVこのシェル変数が非対話のbash(スクリプトの実行など)の起動時に設定されている場合、設定ファイルとして読み込まれ、シェルの初期設定を行います。
シェル変数をファイル名として扱う前にパラメータ展開コマンド置換算術式展開が行われます。
設定ファイルの検索にPATHは使用されません。
BASH_XTRACEFDset -xでトレース情報を出力するファイルディスクリプタとして使用されます。
トレース情報を出力するファイルは予めオープンしておき、その有効なファイルディスクリプタをこのシェル変数に設定する必要があります。
このシェル変数に新しい値を代入すると、それまでのファイルディスクリプタはクローズされ、新しいファイルディスクリプタにトレース情報が書き込まれます。このシェル変数をunsetするか空文字列を代入すると、ファイルディスクリプタはクローズされ、それ以降のトレース情報は標準エラー出力に出力されます。

スクリプトの例:
# トレースファイルの準備と終了処理の登録
XTRACEFILE=~/debug.log
exec {fd}> $XTRACEFILE
if [ $? == 0 ]; then
    trap finally EXIT
    BASH_XTRACEFD=$fd
    set -x
fi

# 終了処理
function finally () {
    exec {fd}>&-
}

# メインの処理
...
  • 変数XTRACEFILEにトレース情報を出力するファイル名を代入します。
  • execコマンドでファイルをオープンして、オープンされたファイルのファイルディスクリプタが代入されます。
  • ファイルが正常にオープンされた場合、trapコマンドで終了処理を登録します。
    これは、スクリプトが予期せず終了した場合、ファイルがオープンされたままになることを防止するための終了処理(ファイルのクローズ)を行います。
  • BASH_XTRACEFDにオープンされたファイルのファイルディスクリプタを代入します。
  • トレース情報を出力するため、set -xを実行します。
  • 任意のメインの処理を記述します。
CDPATHこのシェル変数がcdコマンドの実行時に指定されている場合、ディレクトリを検索するパスとして使用されます。
パスはコロンで区切って複数指定することができます。
例えば、".:~"が指定されている場合、cdコマンドはカレントディレクトリの次に、ホームディレクトリを検索します。
COLUMNS現在のシェルを実行している端末の幅が変更されシグナルSIGWINCHを受信すると自動的に端末の幅が設定されます。
スクリプトでこのシェル変数を参照する場合、シグナルSIGWINCHは端末で実行されている親プロセスのみが受信することにご注意ください。つまり、別プロセスとして実行されているスクリプト内でこのシェル変数を参照してもスクリプトの起動時の値を参照していることとなります。
selectコマンドのリストを表示する際に使用されます。
COMPREPLYbashが補完候補として読み込む単語配列変数です。
プログラム補完機能から呼ばれたシェル関数内で補完候補を設定します。
EMACSこのシェル変数の値がbashの起動時に"t"に設定されている場合、シェルがEmacsのシェルバッファで動作していると見做し行編集を無効にします。
ENVこのシェル変数がPOSIXモードのbashの起動時に設定されている場合、設定ファイルとして読み込まれ、シェルの初期設定を行います。
シェル変数をファイル名として扱う前にパラメータ展開コマンド置換算術式展開が行われます。
設定ファイルの検索にPATHは使用されません。
FCEDITfcコマンドのデフォルトのエディタとして使用されます。
FIGNOREbashがファイル名の補完を行う時にこのシェル変数に設定されているファイルのサフィックスにマッチするファイルは補完候補から除外されます。
例えば、".o:~"をこのシェル変数の値として設定するとファイル名の補完から".o"または"~"で終るファイル名のものは補完候補から除外されます。
force_fignoreが有効化されていない場合、補完候補から除外したサフィックスを持つファイルが唯一の補完候補である場合、除外されずに補完されます。
force_fignoreが有効化されている場合、このシェル変数に設定されているサフィックスにマッチするすべてのファイルは補完候補から除外されます。
FUNCNESTbashはこのシェル変数の値を関数の呼び出しの深さ(ネスト)の最大値として使用します。
0より大きい整数値をこのシェル変数に設定するとそれ以上の深さの関数呼び出しは失敗します。
例として下記のようなスクリプトfuncnest.shを作成します。
#!/usr/bin/bash

# Sub Function A
function func_A () {
    # func_A:6 is called from main:29
    echo ${FUNCNAME[0]}:${LINENO} is called from ${FUNCNAME[1]}:${BASH_LINENO[0]}
    func_B
    return 0
}

# Sub Function B
function func_B () {
    # func_B:14 is called from func_A:7
    echo ${FUNCNAME[0]}:${LINENO} is called from ${FUNCNAME[1]}:${BASH_LINENO[0]}
    func_C
    return 0
}

# Sub Function C
function func_C () {
    # func_C:22 is called from func_B:15
    echo ${FUNCNAME[0]}:${LINENO} is called from ${FUNCNAME[1]}:${BASH_LINENO[0]}

    return 0
}

# メインの処理
FUNCNEST=2
func_A
echo "#### `basename $0` end ####"

実行例:
$ ./funcnest.sh 
func_A:6 is called from main:29
func_B:14 is called from func_A:7
./funcnest.sh: 行 15: func_C: maximum function nesting level exceeded (2)
#### funcnest.sh end ####
GLOBIGNOREbashがパス名展開を行う時にこのシェル変数に設定されているパターンにマッチするファイルは除外されます。
スクリプト内で"*"をワイルドカードではなく、文字列の一部として関数や別のスクリプトの引き数として渡したい場合、GLOBIGNORE=*と設定することでパス名展開で"*"が展開されることを抑止することもできます。
このシェル変数に空文字列以外が指定されると、dotglobオプションが有効となります。
$ touch 1.txt  11.txt  123.txt  123a.txt  A.TXT  a.txt  aa.doc  b.txt  c.txt
$ ls
1.txt  11.txt  123.txt	123a.txt  A.TXT  a.txt	aa.doc	b.txt  c.txt
ファイルをtouchで作成します。

$ echo *
1.txt 11.txt 123.txt 123a.txt A.TXT a.txt aa.doc b.txt c.txt
$ echo ?.*
1.txt A.TXT a.txt b.txt c.txt
最もよく使う*、?をパターンとして指定した例です。

$ GLOBIGNORE=*.txt
$ echo *
A.TXT aa.doc
$ shopt -s extglob
$ GLOBIGNORE=@([[:digit:]]|[[:alpha:]]).txt
$ echo *
11.txt 123.txt 123a.txt A.TXT aa.doc
GLOBIGNOREを設定するとパターンにマッチするファイルが除外されます。
パス名展開に関連するシェルオプションを有効化するとGLOBIGNOREもシェルオプションの設定に従います。
例えば、extglobオプションを有効にして拡張パターンマッチング演算子を使うこともできます。
HISTCONTROLコマンドの履歴リストに履歴を追加する時の動作を制御する以下の値をコロンで区切って指定します。
このシェル変数が設定されていない場合や、無効な値が設定されている場合、HISTIGNOREの設定に従って履歴リストに追加されます。
コマンドが複数行にまたがる複合コマンドの場合、このシェル変数の評価は先頭行のみに対して行われます。
履歴を追加する時の動作
ignorespace空白文字で始まるコマンド行は履歴に追加されません。
ignoredups履歴リストの最後の行に一致する場合、履歴に追加されません。
ignorebothignorespaceとignoredupsの両方を指定したことと等価です。
erasedups追加するコマンド行と一致する過去の履歴が削除され、新しいコマンド行が追加されます。
HISTFILEコマンドの履歴リストを保存するファイル名を指定します。
デフォルト値は~/.bash_historyです。
このシェル変数が設定されていない場合、コマンドの履歴は保存されません。
HISTFILESIZEコマンドの履歴リストファイルに保存する履歴の最大数を指定します。
デフォルト値は500です。
このシェル変数に値が設定されている場合、指定された件数を超えないように古い履歴は削除されます。
HISTIGNOREコマンドの履歴リストに保存しないパターンをコロンで区切って指定します。
パターンはコマンド行の全体と完全一致する必要があります。
ただし、コマンドが複数行にまたがる複合コマンドの場合、このシェル変数の評価は先頭行のみに対して行われます。
'&'はHISTCONTROLのignoredupsと等価です。
'\&'を指定することで履歴リストの最後の行と同じコマンド行を履歴リストに保存することができるようになります。
例えば、HISTIGNORE="&:pwd:ls:ls *"と指定することで、直前のコマンド行と同じコマンド行、lsコマンドを履歴リストの保存から除外することができます。
HISTSIZEメモリ上(キャッシュ)にあるコマンドの履歴リストに保存する履歴の最大数を指定します。
デフォルト値は500です。
シェルの起動時にHISTFILEからメモリに読み込まれ、シェルの終了時に書き出されます。
HISTTIMEFORMATこのシェル変数に空文字列以外が設定されるとコマンドの履歴リストを表示する時に指定された書式のタイムスタンプを表示します。
タイムスタンプは履歴のコメントとしてHISTFILEにも書き込まれます。
書式はstrftime(3)の書式文字列として扱われます。

実行例:
$ HISTTIMEFORMAT="%F %T "
$ history
    1  2022-02-23 23:00:03 HISTTIMEFORMAT="%F %T "
    2  2022-02-23 23:00:06 history
$ HISTTIMEFORMAT="%Y/%m/%d(%A) %T "
$ history
    1  2022/02/23(水曜日) 23:00:03 HISTTIMEFORMAT="%F %T "
    2  2022/02/23(水曜日) 23:00:06 history
    3  2022/02/23(水曜日) 23:01:31 HISTTIMEFORMAT="%Y/%m/%d(%A) %T "
    4  2022/02/23(水曜日) 23:01:33 history
$ HISTTIMEFORMAT="%Y/%m/%d(%a) %T "
$ history
    1  2022/02/23(水) 23:00:03 HISTTIMEFORMAT="%F %T "
    2  2022/02/23(水) 23:00:06 history
    3  2022/02/23(水) 23:01:31 HISTTIMEFORMAT="%Y/%m/%d(%A) %T "
    4  2022/02/23(水) 23:01:33 history
    5  2022/02/23(水) 23:01:40 HISTTIMEFORMAT="%Y/%m/%d(%a) %T "
    6  2022/02/23(水) 23:01:41 history
HOME現在のシェルを起動したユーザーのホームディレクトリが設定されます。
cdコマンドを引き数を指定せずに実行した時のディレクトリとなります。
このシェル変数はチルダ展開の時に参照されます。
HOSTFILEこのシェル変数が設定されている場合、bashはホスト名を補完するために読み込むホストのリストとして参照されます。
ファイルは/etc/hostsと同じフォーマットで記述します。
ファイルの内容が空であったり、読み込みができない場合は/etc/hostsがホストのリストとして参照されます。
このシェル変数の値が変更されると次のホスト名の補完時に新しいファイルの内容を読み込み、現在のメモリ上にあるホストのリストに追加します。
このシェル変数がunsetされるとメモリ上のホストのリストはクリアされます。
$ cat hosts1
192.168.2.1    alpha
192.168.2.2    beta
192.168.2.3    gamma
$ cat hosts2
192.168.3.1    delta
192.168.3.2    epsilon
192.168.3.3    zeta
ホストのリストを記述したファイルhosts1とhosts2を準備します。
$ HOSTFILE=./hosts1
$ 
alpha  beta   gamma
HOSTFILEにhosts1を指定して、Ctrl+X @を入力(CtrlキーとXキーを同時に押下した後、@キーを押下)します。
hosts1に記述されたホスト名が補完候補として表示されます。
$ HOSTFILE=./hosts2
$ 
alpha    beta     delta    epsilon  gamma    zeta
HOSTFILEにhosts2を指定して、Ctrl+X @を入力します。
先程読み込んだホストのリストに加えて、hosts2に記述されたホスト名が補完候補として表示されます。
補完候補はアルファベット順にソートして表示されます。
$ unset HOSTFILE
$ HOSTFILE=./hosts2
$ 
delta    epsilon  zeta
HOSTFILEunsetした後、HOSTFILEにhosts2を指定して、Ctrl+X @を押下します。
メモリ上のホストのリストはクリアされ、hosts2に記述されたホスト名のみが補完候補として表示されます。
IFSbashがコマンド行の展開を行った後に単語の分割をする時やreadコマンドで行を読み込んだ後に単語に分割する場合に単語の区切りを示す文字を設定します。
デフォルト値は<空白文字><タブ文字><改行文字>です。
IGNOREEOF対話型のシェルに対する行頭でのEOF(Ctrl+D)が入力された時の動作を制御します。
IGNOREEOFの設定対話型シェルの動作
整数を設定指定された値の数のEOF(Ctrl+D)が行頭で続けて入力されても無視します。
それ以上のEOFが行頭で入力された場合、シェルを終了します。
整数以外を設定行頭でEOF(Ctrl+D)が10回続けて入力されても無視します。
それ以上のEOFが行頭で入力された場合、シェルを終了します。
空文字列を設定行頭でEOF(Ctrl+D)が10回続けて入力されても無視します。
それ以上のEOFが行頭で入力された場合、シェルを終了します。
変数が未設定行頭でEOF(Ctrl+D)が1回入力された場合、シェルを終了します。
INPUTRCこのシェル変数が設定されている場合、bashはそのファイルをreadlineの設定ファイルとして読み込みます。
設定されていない場合は、デフォルトの設定ファイル~/.inputrcがreadlineの設定ファイルとして読み込まれます。
LANGロケールカテゴリが明示的に設定されていない場合、このシェル変数の値によってロケールを決定します。
LC_ALLこのシェル変数が設定されている場合、他のロケールカテゴリの設定よりも優先され、ロケールを決定します。
LC_COLLATEパス名展開の結果をソートする時の照合順序、パス名展開とパターンマッチングの範囲表現、等値クラス、照合順序を決定します。
LC_CTYPEパス名展開とパターンマッチングの文字の解釈と文字クラスに含まれる文字を決定します。
LC_MESSAGES$に続くダブルクォートされた文字列(通知や診断情報などのメッセージ、および対話型の応答)に関するロケールを決定します。
例として下記のようなスクリプトlocale.shを作成します。
#!/usr/bin/bash

IFS='\n'
printf $"LANG is '%s'.\n" "${LANG}"
printf $"Current time is %s.\n" "$(date)"

メッセージカタログの作成:
$ bash --dump-po-strings locale.sh > locale.sh.po
スクリプトから$""の形式で記述されたメッセージを抽出します。
#: locale.sh:4
msgid "LANG is '%s'.\\n"
msgstr ""
#: locale.sh:5
msgid "Current time is %s.\\n"
msgstr ""
抽出されたメッセージカタログlocale.sh.poは左記のようになっています。
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ja\n"
#: locale.sh:4
msgid "LANG is '%s'.\\n"
msgstr "LANGは'%s'です。\\n"
#: locale.sh:5
msgid "Current time is %s.\\n"
msgstr "現在の時刻は%sです\\n"
  • 作成されたメッセージカタログを左記のように編集します。
  • Content-Type、およびLanguageの設定を行い、その言語にローカライズされたメッセージを記述します。
$ msgfmt -o locale.sh.mo locale.sh.po
$ mkdir -p ja/LC_MESSAGES
$ cp locale.sh.mo ja/LC_MESSAGES/
  • メッセージカタログを翻訳します。
  • メッセージカタログは通常/usr/share/localeなどに格納されますが、ここでは一時的に格納するディレクトリを作成しています。
  • 翻訳されたメッセージカタログを作成した一時ディレクトリにコピーします。
実行例:
$ LANG=C TEXTDOMAINDIR=. TEXTDOMAIN=locale.sh ./locale.sh
LANG is 'C'.
Current time is Fri Feb 26 16:04:46 JST 2022.
$ LANG=en_US.UTF-8 TEXTDOMAINDIR=. TEXTDOMAIN=locale.sh ./locale.sh
LANG is 'en_US.UTF-8'.
Current time is Fri Feb 26 16:04:47 JST 2022.
$ LANG=en_US.UTF-8 LC_MESSAGES=ja_JP.UTF-8 TEXTDOMAINDIR=. TEXTDOMAIN=locale.sh ./locale.sh
LANG is 'en_US.UTF-8'.
現在の時刻はFri Feb 26 16:04:48 JST 2022です
$ LANG=ja_JP.UTF-8 TEXTDOMAINDIR=. TEXTDOMAIN=locale.sh ./locale.sh
LANG is 'ja_JP.UTF-8'.
現在の時刻は2022年  2月 26日 土曜日 16:04:49 JSTです
$ LANG=en_US.UTF-8 LC_ALL=ja_JP.UTF-8 TEXTDOMAINDIR=. TEXTDOMAIN=locale.sh ./locale.sh
LANGは'en_US.UTF-8'です。
現在の時刻は2022年  2月 26日 土曜日 16:04:50 JSTです
LC_ALL > LC_MESSAGES > LANGの順に評価されてメッセージがローカライズされて出力されます。
メッセージカタログは${TEXTDOMAINDIR}/<ロケール>/LC_MESSAGES/${TEXTDOMAIN}.moから読み込まれます。
LC_MONETARY通貨記号、桁区切り文字、符号の位置、小数点以下の桁数など通貨の書式を決定します。
LC_NUMERIC通貨以外の数値の書式を決定します。
LC_TIME月、曜日の表記、および日付と時刻の書式を決定します。
LINES現在のシェルを実行している端末の行数が変更されシグナルSIGWINCHを受信すると自動的に端末の行数が設定されます。
スクリプトでこのシェル変数を参照する場合、シグナルSIGWINCHは端末で実行されている親プロセスのみが受信することにご注意ください。つまり、別プロセスとして実行されているスクリプト内でこのシェル変数を参照してもスクリプトの起動時の値を参照していることとなります。
selectコマンドのリストを表示する際に使用されます。
MAILこのシェル変数にMaildier形式のディレクトリまたは、メールファイルのパスが設定されていて、MAILPATHが設定されていない場合、bashは設定されているパスのファイルをチェックし新しいメールの到着を検出します。
MAILCHECKbashが新しいメールの到着をチェックする頻度を秒数で設定します。
デフォルト値は60秒です。
設定された時間が経過すると次のプロンプトを表示する前に新しいメールの有無をチェックします。
このシェル変数がunsetされるか、0以上の数値以外が設定された場合、メールのチェックは行われません。
MAILPATH新しいメールの到着をチェックするファイル名をコロンで区切って設定します。
ファイル名に続けて?の後に新しいメールが到着した時に表示されるメッセージを設定することができます。
メッセージテキスト中の$_はメールファイル名に展開されます。
設定例:
MAILPATH="/var/mail/$USER?You have mail:~/shell-mail?$_ has mail!"
OPTERRこのシェル変数に0が設定されている場合、getoptsのエラーメッセージ(例えば無効なオプションの指定時など)は全く出力されなくなります。
1が設定されている場合、オプションの処理時のエラーメッセージが出力されます。
このシェル変数はシェルの起動時、およびスクリプトの実行時に1に初期化されます。
PATHシェルが外部コマンドを検索するディレクトリをコロンで区切って設定します。
2つの連続するコロンまたは、先頭か末尾に設定されたコロンはカレントディレクトリを示します。
POSIXLY_CORRECTこのシェル変数がbashの起動時に設定されている場合、--posixオプションを指定した時と同じように他の設定ファイルを読み込む前にPOSIXモードで動作します。
シェルの実行中にこのシェル変数が設定されると、bashはset -o posixを実行した時と同じようにPOSIXモードが有効となります。
PROMPT_COMMANDこのシェル変数が設定されている場合、プライマリプロンプトを出力する前に毎回この値がコマンドとして実行されます。
PROMPT_DIRTRIMこのシェル変数に0よりも大きな整数値が設定されている場合、プロンプト文字列のエスケープシーケンスの\wや\Wを展開する時、ディレクトリがパス名の最後から設定された数だけを残して省略記号に置換されます。
PS1シェルのプライマリプロンプトとして使用され、対話型のシェルのプロンプト文字列(シェルがユーザーコマンドの入力が可能なことを示す文字)として出力されます。
設定されたプロンプト文字列はエスケープシーケンスのデコード後、パラメータ展開コマンド置換算術式展開、クォートの削除が行われます。
展開はシェルオプションpromptvarsの値によって決定されます。
デフォルト値は"\s-\v\$"です。
以下のエスケープシーケンスを使用することができます。
エスケープシーケンス出力される内容
\aASCIIのベル文字(07)を出力します。
ビープ音が鳴ります。
\d"曜日 月 日"の形式の日付を出力します。
\D{format}formatがstrftime(3)の書式文字列として扱われ、指定された書式のタイムスタンプを出力します。
formatが空({}のみ)の場合はロケールで指定された時刻表記を出力します。
\eASCIIのエスケープ文字(033)を出力します。
\hホスト名(FQDNの最初の.までの部分)を出力します。
\Hホスト名をFQDNで出力します。
\jシェルによって管理されている現在のジョブ数を出力します。
\lシェルの端末デバイスのベース名を出力します。
\n改行します。
\r復帰(カーソルを行頭に戻す)します。
\s現在実行しているシェルの名前(${0})のベース名を出力します。
\t24時間制のHH:MM:SS形式の現在の時刻を出力します。
\T12時間制のHH:MM:SS形式の現在の時刻を出力します。
\@12時間制のam/pm形式の現在の時刻を出力します。
\A12時間制のHH:MM形式の現在の時刻を出力します。
\u現在のシェルを実行しているユーザー名を出力します。
\vbashのバージョンを出力します。
\Vbashのリリース(バージョンにパッチレベルを加えたもの)を出力します。
\wカレントディレクトリを出力します。
${HOME}の部分は~に短縮され、${PROMPT_DIRTRIM}の設定が適用されます。
\Wカレントディレクトリのベース名を出力します。
${HOME}の部分は~に短縮されます。
\!コマンド履歴リストにおける次の履歴番号を出力します。
\#現在のシェルにおけるコマンドの番号(コマンドを実行するたびに1つずつ増加)を出力します。
\$現在のシェルの実効UIDが0の場合には#、それ以外の場合は$を出力します。
\nnn8進数値nnnに対応する文字を出力します。
\\\を出力します。
\[非表示文字のシーケンスを開始します。
これを使用してプロンプト文字列中に端末の制御シーケンスを埋め込むことができます。
\]非表示文字のシーケンスを終了します。

SGR (Select Graphic Rendition)を使用するとプロンプト文字列の色を変更することも可能です。
設定例を以下に示します。SGRのサンプルスクリプトも参照ください。
設定例表示例
$ PS1="\u@\h:\W> "
user1@centos7:~> 

シンプルに"ユーザー@ホスト名:カレントディレクトリ> "を出力しています。
$ PS1="\[\e[1;32m\][\A][\u@\h:\w]\$\[\e[0m\] "
$ PS1="\[\033[1;32m\][\A][\u@\h:\w]\$\[\033[0m\] "
$ PS1="\[\e[1;32m\][\$(date +%H:%M)][\u@\h:\w]\$\[\e[0m\] "
[11:21][user1@centos7:~]$ 
3つの例はいずれも同じ結果となります。
プロンプト文字列を太字の緑色("\e[1;32m")に設定し、"[現在の時刻][ユーザー@ホスト名:カレントディレクトリ]$ "を出力しています。
ユーザーが入力するコマンドの文字列が緑色にならないようにプロンプト文字列の最後で"\e[0m"で端末の設定を元に戻しています。
PS2シェルのセカンダリプロンプトとして使用され、継続行などのプロンプト文字列として出力されます。
PS1と同じように展開が行われます。
デフォルト値は"> "です。
PS3selectコマンドのプロンプト文字列として出力されます。
PS4シェルの実行トレース中にbashが表示する各コマンドの前に出力されます。
PS1と同じように展開が行われます。
デフォルト値は"+ "です。
SHELLシェルの完全なパスが保存されています。
シェルを起動した時に設定されていない場合、bashが現在のユーザーログインシェルの完全なパスを設定します。
TIMEFORMATtimeコマンドの時間情報を指定する書式文字列として使用されます。
書式文字列には以下のエスケープシーケンスを使用することができます。
エスケープシーケンス出力される内容
%%文字としての%を出力します。
%[p][l]R経過した秒数を出力します。
%[p][l]Uユーザーモードで消費されたCPUの秒数を出力します。
%[p][l]Sシステムモードで消費されたCPUの秒数を出力します。
%PCPUが消費されたパーセンテージ((%U + %S) / %R)を出力します。

  • [p]: 精度
    省略可能で小数点以下の桁数を0から3までの整数で指定します。
    0を指定した場合、小数点以下は出力されません。
    3より大きな値を指定するか、値を省略した場合は3が指定されたと見做されます。
  • [l]: ロングフォーマット
    省略可能で指定するとMMmSS.FFの形式で分を含みます。
    小数点以下を含むかどうかは、pの指定に従います。
デフォルト値は$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'です。
時間情報を出力する時に末尾に改行文字が付加されます。

実行例:
$ time for ((i=0; i<5000; i++)); do eval echo {0..$i} >/dev/null; done

real    0m6.641s
user    0m6.602s
sys     0m0.040s
$ TIMEFORMAT='%R秒 (System: %3lS User: %3lU) %P%%'
$ time for ((i=0; i<5000; i++)); do eval echo {0..$i} >/dev/null; done
6.601秒 (System: 0m0.041s User: 0m6.561s) 100.00%
$ TIMEFORMAT=$'実行時間:\t%R秒\nシステム:\t%S秒\nユーザー:\t%U秒\nCPU消費:\t%P%%'
$ time for ((i=0; i<5000; i++)); do eval echo {0..$i} >/dev/null; done
実行時間:       6.627秒
システム:       0.040秒
ユーザー:       6.587秒
CPU消費:        100.00%
TMOUTこのシェル変数は以下の3つのタイムアウト値として使用されます。
対象動作
readコマンド デフォルトのタイムアウト値として使用されます。
selectコマンド タイムアウト値として使用され、この値の秒数入力がないと終了します。
対話型シェル プライマリプロンプトを出力してから、この値の秒数を超えてユーザーからの入力がないとbashが終了します。
TMPDIRこのシェル変数が設定されている場合、bashはテンポラリファイルを作成するディレクトリとして使用します。
auto_resumeこのシェル変数が設定されている場合、bashはリダイレクションのない1単語のみの文字列を入力した時、入力された文字列を停止中のジョブの再開候補を選択するため使用します。
このシェル変数に設定されている値によって再開候補のジョブが下記のように選択されます。
auto_resumeの値再開候補のジョブの選択
exact入力された1単語ジョブ名が正確に一致するジョブを選択します。
引き数を持つコマンド複合コマンドなど、複数の単語から成るジョブ名のジョブに一致することはありません。
substring入力された単語を含むジョブ名のジョブを選択します。
上記以外の値入力された単語で始まるジョブ名のジョブを選択します。
複数のジョブが再開候補として一致する場合、最後にアクセスされたジョブが選択されます。

実行例:
$ sleep 600
^Z
[1]+  停止                  sleep 600
$ s
bash: s: コマンドが見つかりませんでした...
$ auto_resume=t
$ s
sleep 600
  1. sleep 600を実行します。
  2. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  3. sを入力します。
    sというコマンドはないためエラーとなります。
  4. auto_resumeに任意の値(ここでは仮に"t"とします)を設定します。
  5. sを入力します。
    sではじまるジョブ名を持つsleep 600コマンドの実行が再開されます。
$ sleep 600
^Z
[1]+  停止                  sleep 600
$ sleep 601
^Z
[2]+  停止                  sleep 601
$ sleep 700
^Z
[3]+  停止                  sleep 700
$ jobs
[1]   停止                  sleep 600
[2]-  停止                  sleep 601
[3]+  停止                  sleep 700
$ auto_resume=substring
$ s
sleep 700
^Z
[3]+  停止                  sleep 700
$ 601
sleep 601
^Z
[2]+  停止                  sleep 601
$ 7
sleep 700
  1. sleep 600を実行します。
  2. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  3. sleep 601を実行します。
  4. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  5. sleep 700を実行します。
  6. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  7. jobsを入力します。
    実行を停止しているジョブとしてsleep 600、sleep 601、sleep 700の3つのコマンドが表示されます。
  8. auto_resumeの値としてsubstringを設定します。
  9. sを入力します。
    ジョブ名にsを含むジョブのうち、最後に実行したsleep 700コマンドの実行が再開されます。
  10. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  11. 601を入力します。
    ジョブ名に601を含むジョブとしてsleep 601コマンドの実行が再開されます。
  12. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  13. 7を入力します。
    ジョブ名に7を含むジョブとしてsleep 700コマンドの実行が再開されます。
#!/usr/bin/bash

sleep 600
$ ./sleep.sh
^Z
[1]+  停止                  ./sleep.sh
$ sleep 600
^Z
[2]+  停止                  sleep 600
$ jobs
[1]-  停止                  ./sleep.sh
[2]+  停止                  sleep 600
$ auto_resume=exact
$ sleep
sleep: オペランドがありません
Try 'sleep --help' for more information.
$ ./sleep.sh
./sleep.sh
  1. sleep 600をスクリプトsleep.shとして作成します。
  2. ./sleep.shを実行します。
  3. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  4. sleep 600を実行します。
  5. Ctrl+Zを入力します。
    実行中のコマンドがバックグラウンドに移動し、停止します。
  6. jobsを入力します。
    実行を停止しているジョブとして./sleep.sh、sleep 600の2つのコマンドが表示されます。
  7. auto_resumeの値としてexactを設定します。
  8. sleepを入力します。
    sleepコマンドは引き数が必須なためエラーとなります。
  9. ./sleep.shを入力します。
    sleep.shが新たに実行されることなく、ジョブ名が./sleep.shと正確に一致するジョブの実行が再開されます。
histcharsコマンドの履歴を展開する文字、履歴の簡易置換を行う文字、それ以降をコメントとして扱う文字を指定します。
これらは以下のように2文字または3文字で設定します。
 設定される内容
1文字目履歴の展開を指示する文字を指定します。
通常は'!'です。
2文字目直前に入力したコマンド文字列の一部を置換する場合の区切り文字(置換対象と、置換する文字列を囲んで指定)を指定します。
3文字目この文字以降をコメントとして扱い、履歴の置換をスキップします。
HISTTIMEFORMATが設定されている場合、HISTFILEに書き込まれるタイムスタンプの行頭文字もこの文字に変更されることにご注意ください。


実行例:
$ histchars='!^#'
$ touch file
$ ^touch^ls -l^
$ ls -l file
-rw-rw-r--. 1 user1 user1 0  2月 26 08:58 file
$ ^ls -l^rm^
$ rm file
rm: 通常の空ファイル `file' を削除しますか? y
$ cd /tmp
$ ^/tmp^/var/tmp^
$ cd /var/tmp
$ echo Hello Hello
Hello Hello
$ ^Hello^こんにちは^
$ echo こんにちは Hello
こんにちは Hello
$ echo Hello World
Hello World
$ echo !$ @ !$ # !$
$ echo World @ World # !$
World @ World
$ histchars='!^@'
$ echo Hello World
Hello World
$ echo !$ @ !$ # !$
$ echo World @ !$ # !$
World @ !$
  1. histcharsの値として'!^#'を設定します。
  2. fileをtouchコマンドで作成します。
  3. ^touch^ls -l^を入力します。
    直前のコマンドのtouchがls -lに置換されます。
  4. ^ls -l^rm^を入力します。
    直前のコマンドのls -lがrmに置換されます。
  5. cdコマンドでカレントディレクトリを/tmpに変更します。
  6. ^/tmp^/var/tmp^を入力します。
    直前のコマンドの/tmpが/var/tmpに置換されます。
  7. echoコマンドでHello Helloを出力します。
    Hello Helloが標準出力に出力されます。
  8. ^Hello^こんにちはを入力します。※最後の^は省略可能です。
    直前のコマンドの最初のHelloがこんにちはに置換されます。
  9. echoコマンドでHello Worldを出力します。
    Hello Worldが標準出力に出力されます。
  10. echo !$ @ !$ # !$を入力します。
    !$が直前のコマンドの最後の引き数に置換されます。
    #以降はコメントとして扱われるため置換の対象となりません。
    結果としてecho World @ World # !$という文字列に置換されます。
  11. histcharsの値として'!^@'を設定します。
  12. echoコマンドでHello Worldを出力します。
    Hello Worldが標準出力に出力されます。
  13. echo !$ @ !$ # !$を入力します。
    !$が直前のコマンドの最後の引き数に置換されます。
    @以降はコメントとして扱われるため置換の対象となりません。
    結果としてecho World @ !$ # !$という文字列に置換されます。
    ただし、シェルとしてのコメントの始まりを示す文字は#のままです。