Bashの変数の基本:設定・削除・子プロセスへの渡し方を実例付きで解説
コンピュータサイエンス(そして日常的なコンピューティング)において、変数とは、後で使う情報を一時的に保持しておくメモリ上の場所のことです。言い換えれば、データを入れたり取り出したりするための一時的な保管容器です。Bashシェルでは、そのデータは単語(コンピュータ用語では「文字列」)でも数値(「整数」)でも構いません。
パソコンで意識的に変数を使ったことがない人でも、生活の中では変数に相当するものを使っているはずです。「あれを取って」「これを見て」といった言葉は、文法上の変数(代名詞)です。「これ」や「あれ」が何を指すのかは、話し手が頭の中で思い浮かべているものや指差している対象によって決まります。数学でも、未知の値を表すために変数を使いますが、それを「変数」と呼んでいる人は少ないかもしれません。
実は、毎日無意識に使っているBash変数の例があります。PS1変数は、ターミナルのプロンプトの見た目に関する情報を保持しています。たとえば、ごくシンプルなパーセント記号(%)だけのプロンプトにしたい場合は、PS1変数を再定義します:
$ PS1="% "
%
この記事では、Linux、BSD、Mac、Cygwin上で動作するBashシェルにおける変数について解説します。MicrosoftのオープンソースであるPowerShellをお使いの方は、PowerShellの変数に関する記事を参照してください。
変数は何のためにあるのか?
Bashで変数が必要かどうかは、ターミナルで何をするかによります。あるユーザーにとって変数はデータ管理に不可欠な手段であり、別のユーザーにとっては些細で一時的な便利機能にすぎず、さらに別のユーザーにとっては存在しないも同然かもしれません。
結局のところ、変数は道具の一つです。用途があれば使えばいいし、OSが管理してくれると安心して放置してもかまいません。しかし知識は力です。Bashでの変数の仕組みを理解すれば、思いもよらない創造的な問題解決につながることもあります。
変数の設定方法
変数を作成するのに特別な権限は必要ありません。作成も使用も自由で、基本的に無害です。LinuxやMacのBashシェルでは、変数名を定義して値を設定するだけで変数を設定できます。次の例では、FOOという新しい変数を作成し、文字列/home/seth/Documentsを設定しています:
$ declare FOO="/home/seth/Documents"
成功した場合は不気味なほど静かなので、変数が正しく設定されたか確信が持てないかもしれません。echoコマンドで結果を確認できます。変数を参照するときは、ドル記号($)を先頭に付けます。変数が定義どおりに正確に読み取られるようにするには、波括弧と引用符で囲むのも有効です。こうすることで、変数内の特殊文字が保護されます。この例では必要ありませんが、良い習慣として身につけておきましょう:
$ echo "${FOO}"
/home/seth/Documents
シェルを頻繁に使う人にとって変数の設定は日常的な操作なので、手順はやや略式的になっています。文字列の後に等号(=)と値が続くと、Bashは黙って変数の設定だと判断し、declareキーワードは不要になります:
$ FOO="/home/seth/Documents"
変数は通常、あるシステムから別のシステムへ情報を受け渡すためのものです。この簡単な例ではあまり役に立ちませんが、それでも情報を伝えることはできます。たとえば、FOO変数の中身がファイルパスなので、~/Documentsディレクトリへのショートカットとして使えます:
$ pwd
/home/seth
$ cd "${FOO}"
$ pwd
/home/seth/Documents
変数名には、予約されていない任意の文字列(整数とアンダースコアを含む)を使えます。大文字にする必要はありませんが、変数と一目でわかるように大文字にすることが多いです。
変数の削除方法
変数はunsetコマンドで削除できます:
$ unset FOO
$ echo $FOO
実際には、この操作はあまり必要ありません。変数は比較的「安価」なので、作成したまま不要になったら忘れてしまっても問題ありません。ただし、変数が空であることを保証したい場合もあります。それは、その変数を読み取るかもしれない別のプロセスに誤った情報を渡さないようにするためです。
衝突保護付きで新しい変数を作成する
場合によっては、自分やプロセスによってすでに変数が設定されている可能性があることもあります。それを上書きしたくなければ、既存の値が空でない限り既存の値を優先する特別な構文があります。
この例では、FOOが/home/seth/Documentsに設定されていると仮定します:
$ FOO=${FOO:-"bar"}
$ echo $FOO
/home/seth/Documents
コロンとダッシュの:-表記により、既存の値があればそれがデフォルトとして使われます。逆の動作を確認するには、変数をクリアして再試行します:
$ unset FOO
$ echo $FOO
$ FOO=${FOO:-"bar"}
$ echo $FOO
bar
変数を子プロセスに渡す
変数を作成すると、「ローカル変数」と呼ばれるものが作られます。これは、その変数が現在のシェルにのみ認識されることを意味します。
これは変数の「スコープ」を意図的に制限する仕組みです。変数は設計上、デフォルトでローカルのみ利用可能になっており、情報共有を必要最小限に抑えるようになっています。たとえば、重要なパスワードを平文で含む変数をうかつに作成した場合でも、その変数を作成したセッション以外(リモートシェルや不正なデーモンなど)がそのパスワードにアクセスできないことは心強いでしょう。
記事冒頭の例を使ってプロンプトを変更し、現在のシェル内で新しいシェルを起動してみましょう:
$ PS1="% "
% bash
$
新しいシェルを起動すると、PS1の新しい値ではなくデフォルトのプロンプトが表示されます。子プロセスは親で設定された変数を継承しないためです。子プロセスを終了すると親シェルに戻り、カスタムのPS1プロンプトが再び表示されます:
$ exit
%
変数を子プロセスに渡したい場合は、コマンドの前に変数定義を「前置」するか、変数を子プロセスに「エクスポート」します。
変数の前置
コマンドを実行する前に、任意の数の変数を前置できます。子プロセスがその変数を使用するかどうかはプロセス次第ですが、いずれにせよ変数を渡すことはできます:
$ FOO=123 bash
$ echo $FOO
123
$
前置は、特定のライブラリの場所を必要とするアプリケーションを実行する場合(LD_LIBRARY_PATH変数を使用)、非標準のコンパイラでソフトウェアをビルドする場合(CC変数を使用)などに便利なテクニックです。
変数のエクスポート
子プロセスで変数を利用可能にするもう一つの方法は、exportキーワードです。これはBashに組み込まれたコマンドで、指定した変数のスコープを広げます:
$ PS1="% "
$ FOO=123
$ export PS1
$ export FOO
% bash
% echo $PS1
%
% echo $FOO
123
どちらの場合も、ローカル変数にアクセスできるのは子シェルだけではなく、そのシェルの子プロセスすべてです。同じシェルからアプリケーションを起動すれば、その変数はアプリケーション内から環境変数として利用できます。
システム全体で使えるようエクスポートされた変数は「環境変数」と呼ばれ、これは今後の記事のテーマです。それまでの間、日常のタスクでいくつか変数を使ってみて、ワークフローにどんな変化をもたらすか試してみてください。
-
Linux Bashのネストした変数置換とevalコマンド、事前定義変数一覧 – パート11
これまでのBashシェルに関する記事、特に変数について詳しく解説した2本の記事は、読者の皆様から高い評価をいただきました。Tecmintチームとしては、最新かつ関連性の高いトピックを詳細に提供することを心がけており、常に各テーマの重要な観点にも触れるよう努めています。今回の記事はLinux変数シリーズの最終回です。変数の置換(Variable Substitution)と、シェルにあらかじめ定義されている変数について解説し、このテーマを締めくくりましょう。Bashにおける変数置換の仕組みBashは、コマンドが実際に実行される前に変数の置換を行います。Bashシェルはコマンド実行前にすべての「$
-
Bash変数チュートリアル – 基本からグローバル変数・ローカル変数まで学べる6つの実用例
Bash変数は、プログラムの実行期間中に必要となる情報を一時的に保存しておくための仕組みです。本記事はBashチュートリアルシリーズの一篇で、他のプログラミング言語と同様にBashでも変数を利用できることを踏まえ、基本的な使い方からグローバル変数とローカル変数の違いまでを、6つの実用的なサンプルを通じて解説します。 Bash変数の基本構文 変数の定義は非常にシンプルで、次の書式に従います。 VARNAME=VALUE 注意: 変数へ代入する際は、「=」記号の前後にスペースを入れてはいけません。「VAR=VALUE」のように書けば、シェルは「=」を代入記号として認識し、この行を変数への代入とし