Lから始まるLinux

2章40話
シェル変数
2章41話 コマンド置換
もくじ
2章42話
算術式展開
コマンド置換
若木 みどり
お兄ちゃん! コマンドの出力を 変数の値にしたいんだけど できそうでできないんだ… リダイレクトやパイプ、 プロセス置換じゃないよね?
若木 しげる
それは 「コマンド置換 (command substitution)」 の出番だね コマンド出力を 文字列にしてくれるんだ!
バッククォートでのコマンド置換
若木 しげる
nproc CPU のコア数を表示するよ
nproc [オプション]...
若木 しげる
重要なオプションはないのでそのまま実行してみよう!
nproc
若木 みどり
うん!
4
若木 みどり
このシステムにはCPU のコアが4つあるんだね!
若木 しげる
この結果をCORES 変数に保存してみよう!
若木 みどり
こう書けばいいんだよね?
CORES=4
若木 みどり
確かにコアの数は保存できたけど…これだと毎回 nproc で調べて値を指定しなきゃいけないよね私のやりたかったことには届いていない感じかな
若木 しげる
そこで便利なのがコマンド置換だよ以下のようにコマンドを「バッククォート(`)」で囲むとコマンドの出力がそのまま文字列となって変数の値として使えるんだ
CORES="`nproc`"
若木 みどり
これで本当にCORES の値が4 になったのかな?
若木 しげる
それは以下のコマンドで確認してみよう!
echo "$CORES"
若木 みどり(驚き)
なるほど…echo で変数の値を表示して確認できるのね!
4
若木 みどり(笑顔)
本当だ!ちゃんと 4表示されたよ!
$( ... ) でのコマンド置換
若木 しげる
バッククォートは古い書き方なんだ最近のシェルでは以下のように書くよ
CORES="$(nproc)"
若木 みどり
こっちの書き方だとコマンド置換の始まりと終わりが分かりやすいね!
若木 しげる
他にもクォートの入れ子も柔軟に解釈してくれるんだ
MESSAGE="$(echo "hello, $USER")"
若木 みどり
ただダブルクォートの出現順で判断するのではなく"$( ... )" の中に"hello, ..." があると賢く判断してくれるんだね
若木 しげる
なので可能なら $( ... )コマンド置換を書くようにしよう!
ダブルクォートで囲む
若木 みどり
お兄ちゃんはシェル変数やコマンド置換をいつも「ダブルクォート(")」囲んでいるよね?
若木 しげる
よく気が付いたね!意識的にそうしているんだ
若木 みどり
そうすることで何かいいことがあるのかな?
若木 しげる
「ダブルクォート(")」で囲むとそれが1つのまとまりであることが保証されるんだ
若木 しげる
例えば "$(コマンド)" としたときにコマンドが何も出力しなくても空文字になるしrmdir "$DIR" を実行したときにDIR 変数の値が Program Filesスペースが含まれていても問題ないんだ
若木 みどり
「転ばぬ先の杖」みたいだね!私も真似して書いてみるよ!
まとめ
若木 みどり
「コマンド置換」でコマンドの出力を文字列として扱う方法を学んだよ!
若木 しげる
コマンド置換は高度な操作でよく使われるよ$( ... ) でコマンドを文字列に置き換えよう