HOMEには/home/labが設定されている。
変数の値ではなく、5文字の$HOMEをそのまま表示する。
適切なコマンドはどれか。
Bashのシングルクォート内では、各文字がリテラルとして扱われる。ダブルクォート内では$による展開が残る。
詳細解説
printf '%s\n' "$HOME"ダブルクォート内ではパラメータ展開が行われ、/home/labになる。
ダブルクォートは$HOMEの展開を止めない。この設問の値なら/home/labを1つの引数としてprintfに渡す。展開の有無と、展開結果を1引数に保つことは別の役割である。
printf '%s\n' $HOMEクォートがなくても$HOMEは展開される。
この設問の/home/labには空白がないため、値はaと同じように表示される。しかし$HOMEそのものは残らない。一般には引用されていない展開結果が単語分割やファイル名展開を受け得るので、常にaと同じ動作だとは考えない。
printf '%s\n' '$HOME'シングルクォートは$を含む文字列をそのまま保持する。
シェルが$HOMEを展開せず、その5文字をprintfのデータ引数へ渡す。表示用の引用符自体は出力に含まれない。printfの書式と、表示するデータの引用符を別々に読む。
printf '%s\n' "HOME"$記号を含まないためHOMEだけを表示する。
ダブルクォートの中身はHOMEという4文字であり、ドル記号が最初からない。変数展開の選択だけでなく、必要な5文字がデータにそろっているかを確認する。
実際に確かめる
一時的な検証環境で実行できる例です。
printf '%s\n' '$HOME'
LAB_TEXT='two words'
printf 'quoted=<%s>\n' "$LAB_TEXT"
printf 'unquoted=<%s>\n' $LAB_TEXT参考にした公式資料
期待される結果
$HOME
quoted=<two words>
unquoted=<two>
unquoted=<words>理解のポイント
- シングルクォート
- ダブルクォート
- パラメータ展開
確認時の注意
- 確認環境: Bash 5.2、新規プロセス、通常のIFS(空白・タブ・改行)。HOMEの値は変更せず確認する。
- 最初の行はHOMEの値を参照せず、文字列$HOMEを表示する。検証のために普段のHOMEを変更する必要はない。
- 後半のLAB_TEXTは単語分割を確認する補助例。通常のIFSで新規Bashを使い、quotedの1行とunquotedの2行を比べる。
基礎のおさらい
展開と引数数を分ける
シングルクォートは文字を保持し、ダブルクォートは変数を展開しながら通常のスカラー値を1引数に保つ。この設問の目的は値ではなく$HOMEという表記を表示することである。
出力の差を前提に合わせて読む
/home/labという値では引用なしでも同じ値に見える。補助例two wordsを使うと、引用時の1引数と引用なしの2引数の違いをprintfの繰り返しで確認できる。
シェルとprintfの役割
展開と引用符の除去はシェルが行う。printfは受け取った引数を%sで表示し、書式中のバックスラッシュnを改行として扱う。