Linux Bashのネストした変数置換とevalコマンド、事前定義変数一覧 – パート11
これまでのBashシェルに関する記事、特に変数について詳しく解説した2本の記事は、読者の皆様から高い評価をいただきました。Tecmintチームとしては、最新かつ関連性の高いトピックを詳細に提供することを心がけており、常に各テーマの重要な観点にも触れるよう努めています。
今回の記事はLinux変数シリーズの最終回です。変数の置換(Variable Substitution)と、シェルにあらかじめ定義されている変数について解説し、このテーマを締めくくりましょう。
Bashにおける変数置換の仕組み
Bashは、コマンドが実際に実行される前に変数の置換を行います。Bashシェルはコマンド実行前にすべての「$」記号を検索し、それを対応する変数の値に置き換えます。この置換プロセスは一度だけ実行される点に注意が必要です。
では、ネストした変数(入れ子になった変数)の場合はどうなるのでしょうか?
注: ここでいう「ネストした変数」とは、変数の中で宣言された変数のことを指します。以下の例で実際に確認してみましょう。
まず、読み取り専用(-r)かつエクスポート可能(-x)な変数を宣言します。
admin@wsxdn.com:~$ declare -rx Linux_best_website="www.tecmint.com"
変数に格納された値を確認します。
admin@wsxdn.com:~$ printf "%s" "$Linux_best_website"
www.tecmint.com
次に、同じく読み取り専用かつエクスポート可能な別の変数を宣言します。
admin@wsxdn.com:~$ declare -rx Linux_website="Linux_best_website"
これで2つの変数が定義されました。
- 「Linux_best_website」の値は「www.tecmint.com」
- 「Linux_website」の値は「Linux_best_website」
以下のコマンドを実行すると、どのような結果になるでしょうか?
admin@wsxdn.com:~$ printf "%s" "$Linux_website"
理想的には、まず変数「$Linux_website」が値「Linux_best_website」に置き換えられ、さらに「$Linux_best_website」も変数なので、その値「www.tecmint.com」へと置き換えられるはずです。つまり、最終的な出力は次のようになると期待されます。
admin@wsxdn.com:~$ printf "%s" "$Linux_website"
www.tecmint.com
しかし残念ながら、実際に出力されるのは「Linux_best_website」という文字列そのものです。
その理由は?そう、Bashは変数の値を一度しか置換しないためです。では、複雑なスクリプトやプログラムで、変数を頻繁に、しかも複数回置換する必要がある場合はどうすればよいのでしょうか?
evalコマンドで複数回の変数置換を実現する
ここで登場するのが「eval」コマンドです。このコマンドは、スクリプト内で変数の置換を複数回行う追加処理を実行してくれます。以下の例で、その動作を明確に理解しましょう。
値が10である変数xを宣言します。
admin@wsxdn.com:~/Desktop$ declare x=10
定義した変数xの値を確認します。
admin@wsxdn.com:~/Desktop$ echo $x
10
続いて、値が「x」である変数yを宣言します。
admin@wsxdn.com:~/Desktop$ declare y=x
定義した変数yの値を確認します。
admin@wsxdn.com:~/Desktop$ echo $y
x
ここで問題になるのが、Bashの変数置換が1回限りであり、余分な置換ラウンドを実行してくれないという点です。この問題を解決するために「eval」コマンドを使用します。
admin@wsxdn.com:~/Desktop$ eval y=$x
改めて変数yの値を確認してみましょう。
admin@wsxdn.com:~/Desktop$ echo $y
10
成功です!問題は無事に解決され、「eval」コマンドが見事にその役割を果たしました :)
言うまでもなく、「eval」コマンドは大規模なスクリプトプログラムにおいて非常に有用で、覚えておくと便利な強力なツールです。ただし、外部からの入力をそのままevalに渡すと任意のコード実行につながる危険があるため、使用する際は入力内容の検証を忘れないようにしましょう。
Bashの事前定義変数一覧
最後に紹介するのは、Bashの事前定義変数(Predefined Variables)です。このリストを見て驚かないでください。スクリプト作成を始めるにあたって、一部を除いて全リストを暗記する必要はありません。学習の一環として、よく使われるBashの事前定義変数を表にまとめました。
| No. | 変数名 | 説明 |
| 1 | auto_resume | 停止中のジョブに対するコマンド補完の処理方法 |
| 2 | BASH | シェルのパス |
| 3 | BASH_ENV | 起動時に読み込まれるプロファイルファイルの名前 |
| 4 | BASH_VERSION | Bashのバージョン |
| 5 | BASH_VERSINFO | 詳細なバージョン情報 |
| 6 | BASH_VERSINFO[0] | メジャーバージョン番号(リリース) |
| 7 | BASH_VERSINFO[1] | マイナーバージョン番号(バージョン) |
| 8 | BASH_VERSINFO[2] | パッチレベル |
| 9 | BASH_VERSINFO[3] | ビルドバージョン |
| 10 | BASH_VERSINFO[4] | リリースステータス(例: beta1) |
| 11 | BASH_VERSINFO[5] | MACHTYPEの値 |
| 12 | CDPATH | cdコマンドの検索対象となる、コロン区切りのディレクトリリスト |
| 13 | COLUMNS | 標準出力の1行あたりの文字数 |
| 14 | EUID | 現在のユーザーの実効ユーザーID |
| 15 | FCEDIT | fcコマンドで使用されるデフォルトのテキストエディタ |
| 16 | FUNCNAME | 実行中の関数の名前 |
| 17 | GROUPS | ユーザーが所属するグループのリスト |
| 18 | HISTFILE | コマンド履歴を保存するファイル |
| 19 | HOME | ホームディレクトリのパス |
| 20 | LINES | 標準出力の水平方向の行数 |
| 21 | 受信メールをチェックするファイルの名前 | |
| 22 | OSTYPE | オペレーティングシステムの種類 |
| 23 | OLDPWD | 直前の作業ディレクトリ |
| 24 | PWD | 現在の作業ディレクトリ |
| 25 | RANDOM | 参照するたびに乱数を返す |
| 26 | SHELL | ログインシェルとして優先されるシェル |
| 27 | TIMEFORMAT | timeコマンドの出力フォーマット |
| 28 | UID | 現在のユーザーのユーザーID |
Bashには他にも多数の事前定義変数が存在しますが、ここでは日常的によく使われるものを厳選してご紹介しました。
今回は以上です。また別の興味深い記事でお会いしましょう。それまでTecMintをお楽しみに。貴重なフィードバックがあれば、ぜひ下のコメント欄でお聞かせください。
-
Linuxシェルスクリプト入門:変数の基本を徹底解説(第9回)
これまでLinuxシェルスクリプティングに関する連載記事をお届けしてきましたが、当時は多くの方にご好評いただき、今でも十分に役立つ内容となっています。ここでは、変数の仕組み、実行方法、そしてシェルスクリプトでの実装について詳しく見ていきます。 コマンド出力の保存 コマンドの出力は標準出力やファイルにリダイレクトできるだけでなく、変数に格納することも可能です。コマンドの出力が大きすぎて画面に収まらない場合は、ファイルまたは変数に出力を保存するしかありません。変数に出力を保存する利点の一つは、確認速度が速いことです。変数はメモリ上に保存されるため、ファイルからの読み出しと比べて高速に処理されます。
-
Bash変数チュートリアル – 基本からグローバル変数・ローカル変数まで学べる6つの実用例
Bash変数は、プログラムの実行期間中に必要となる情報を一時的に保存しておくための仕組みです。本記事はBashチュートリアルシリーズの一篇で、他のプログラミング言語と同様にBashでも変数を利用できることを踏まえ、基本的な使い方からグローバル変数とローカル変数の違いまでを、6つの実用的なサンプルを通じて解説します。 Bash変数の基本構文 変数の定義は非常にシンプルで、次の書式に従います。 VARNAME=VALUE 注意: 変数へ代入する際は、「=」記号の前後にスペースを入れてはいけません。「VAR=VALUE」のように書けば、シェルは「=」を代入記号として認識し、この行を変数への代入とし