uname -rは実行中カーネルのリリース文字列を出力する。
その出力をLAB_KERNELへ保存する。
適切なコマンドはどれか。
$(...)はコマンドの標準出力へ置き換わる。代入と組み合わせると、結果をシェル変数へ保存できる。
詳細解説
LAB_KERNEL='uname -r'コマンドを実行せず、文字列uname -rを保存する。
引用符の中のuname -rは文字列であり、この候補ではunameが実行されない。実行されるコマンドの出力と、コマンド名を書いた文字列のどちらが保存されるかを見分ける。
uname -r > LAB_KERNELLAB_KERNELというファイルへ出力し、変数には保存しない。
LAB_KERNELは>の出力先ファイル名であり、同名の変数は設定されない。通常の>は既存ファイルを切り詰め得るため、候補を比較するときは新しい一時ディレクトリを使う。
$(uname -r)置換結果をコマンド名として実行しようとし、変数代入がない。
代入語がなく、置換結果がコマンド名の位置に現れる。出力された名前を実行しようとするので、必ず特定のエラーになるとは限らないが、LAB_KERNELへの保存は行わない。
LAB_KERNEL=$(uname -r)コマンド置換の出力を変数へ代入する。
uname -rの標準出力が置換され、その末尾改行を除いた値がLAB_KERNELへ代入される。代入の右辺では通常の単語分割やファイル名展開を行わない。後から表示する際は"$LAB_KERNEL"と引用する。
実際に確かめる
一時的な検証環境で実行できる例です。
LAB_KERNEL=$(uname -r)
if [[ -n "$LAB_KERNEL" && "$LAB_KERNEL" == "$(uname -r)" ]]; then printf 'release-match=yes\n'; else printf 'release-match=no\n'; fi
LAB_SAMPLE=$(printf 'line one\nline two\n\n')
printf 'sample=<%s>\n' "$LAB_SAMPLE"参考にした公式資料
期待される結果
release-match=yes
sample=<line one
line two>理解のポイント
- コマンド置換
- 標準出力
- 変数代入
確認時の注意
- 確認環境: Bash 5.2 / GNU coreutils uname。リリース文字列はホスト依存のため固定値を仮定しない。出力保存の再現はBash 5.2.37 / GNU coreutils 8.32(Git Bash)で確認。
- リリース文字列は環境によって違うため、空でなくuname -rと一致するかをrelease-matchで確認する。後半のline one/line twoは改行処理を再現する補助データで、実際のカーネルのリリース値ではない。
- 通常のコマンド置換が受け取るのは標準出力。標準エラーまで自動的に保存されるわけではない。値を再利用するときはダブルクォートする。
基礎のおさらい
末尾と内部の改行
通常の$(...)は出力末尾の改行をすべて取り除く。内部の改行は残るため、検証では末尾に2つの改行を持つ補助出力を引用して表示する。
代入とコマンド位置
代入語にある=の右辺で置換するのか、単独のコマンド位置で置換するのかで結果の用途が変わる。出力を得るだけでは名前付き変数へ保存したことにはならない。
ファイルと変数は別
> LAB_KERNELはファイルへの出力であり、LAB_KERNEL=$(...)は変数への代入である。同じ綴りでも構文上の位置が違う。