クイズ: Bash & Shell マスター
コンピュータとちゃんと話せますか?
この16問のクイズでBashスクリプトスキルをテストしてみましょう!
変数、ループ、条件分岐、文字列操作、関数、そして基本からやや複雑な構文の落とし穴までをカバーします。
シェルスクリプトのスキルを磨く(または証明する)!
Bashでの変数宣言は=の前後にスペースを付けません。例えば:
これはname変数に"Alice"を代入します。
注:$nameは変数の参照や値の読み取りに使用されます。
スペースを追加するとシェルがコマンドとして解釈してしまい、変数設定の意図に反します。
また、Bashは大文字小文字を区別するため、name、NAME、Nameは別の変数になります。
最後に、変数名にスペースやハイフン(-)は使用できません。アンダースコア(_)やcamelCaseを使用してください。
「It’s 🔨 Time!」を出力するコマンドはどれですか?
クォートのエスケープは本当にややこしいですよね。Bash文字列内で他の言語をエスケープする想像してみてください。クォートやアポストロフ、$記号が邪魔になります。🫠
シングルクォート内ではシングルクォートをエスケープする必要があります。'\''というクォート→エスケープ→クォートのシーケンスで出力できます:
他の方法もありますが、これは最も一般的な方法です。
大括弧{}による拡張は、コンマ区切りの値やパターンごとに、文字列コンテキストの複数バージョンを生成します。
ここではc{a,b}tは次のように展開されます:
番号付きの変数は特殊な意味を持ちます。このケースでは、$1はスクリプトまたは関数に渡された最初の引数を保持する特殊な変数です。
REPL環境でスクリプトを実行しているため、引数が存在しないため$1は空になります。残りの文字00はそのまま出力されます。
リテラルの$文字を出力するには、シングルクォートを使用するか、バックスラッシュでエスケープしてください(\):
${var/pattern/replacement} 構文は、pattern の最初の出現を replacement で置換します。ここでの出力は:
これは大文字小文字を区別します。bark と Bark の両方を処理するには、${var/[Bb]ark/Bark} のようなパターンを使用するか、置換前に文字列を正規化してください。
すべての出現を置換するには ${var//pattern/replacement} を、
文字列の先頭から置換するには ${var/#pattern/replacement} を、
文字列の末尾から置換するには ${var/%pattern/replacement} を使用します。
${#username}構文はusernameの長さを返します。
例:
wcは機能しますが、これは厳密にBashの一部ではありません。
wcユーティリティは古くからあるジョークで「water closet(トイレ)」を指していました。
ジョークです!誰かこれらを読んでいるのでしょうか?
実際にはwcはPosix(およびAT&T Unix時代)からの古いコマンドで、ファイルや入力ストリームの行数・単語数・文字数をカウントします。
ファイルcats.txtが存在する場合、このスクリプトは何を出力しますか?
echo "File does not exist"
閉じ括弧の前のスペースが不足していることに気づけましたか?
Bashはここでは非常に敏感です: 括弧内にスペースが必要です。
スペースの不足により[コマンドが閉じ ]を見逃し、Bashは診断メッセージを表示し、テストを失敗扱いにしてelseブランチに進みます。
正しい構文は次の通りです:
if [ -e example.txt ]; then
echo "File does not exist"
注: 条件式には**二重括弧[[ ]]**の使用を推奨します。BashFAQを参照してください。
Bashで文字列を比較する方法は?
if [ "$cat1" === "$cat2" ]; then
別のテスト構文エラー!
無効な===演算子に気づきましたか?
JavaScriptを思い出したかもしれませんね…
[ ... ]ではBashは診断情報を報告し、条件がfalseになるためelse分岐でDifferent catsを出力します。Bashでは等価比較に=または==を使用してください。
Bashの関数は引数を受け取ることができます。$1変数は関数に渡された最初の引数を保持します。
覚えておきましょう。$0はスクリプト名、$1は最初の引数、$2は2番目の引数であり、スペースで引数が区切られます。したがって、greet Hi Danは"Hi"を最初の引数として渡します。"Hi Dan"を単一の引数として渡すには、クォートが必要です:greet "Hi Dan"。
コマンドの出力を次のコマンドの入力に接続する演算子は何ですか?
パイプ演算子|は、1つのコマンドの出力を別のコマンドの入力に接続します。例えば:
echo "Mr. Levy 👨🏻🔬" | wc -m
(( ))の構文はBashで整数算術を実行します。
簡単な計算に使用できます:
条件式にも利用可能です:
echo "2 is greater than 1"
浮動小数点演算が必要な場合は、bcやawkの利用を検討してください。
これらのうち、10と0.5を掛けて5を出力するのはどれですか?
(( ))の構文は整数算術のみを実行します。小数点を含む浮動小数点計算はサポートされていません!
Bashは(驚くべきことに)組み込みの浮動小数点算術サポートを持っていません。
最も一般的な解決策は、GNUユーティリティbcやawkを使うことです。
このスクリプトで:はどのような働きをするか?
rosie="Bad cat, good cat"
${var:offset}という構文は、offsetから始まる部分文字列を抽出します。ここでは、出力は次のようになります:
特定の長さの部分文字列を抽出するには${var:offset:length}を使用します。
文字列の末尾から抽出するには${var: -offset}を使います。(-の前にスペースがあることに注意!)
Bashでルーピングのキーワードでないのはどれですか?❌
eachはBashのループキーワードではありません。主なループキーワードはfor、while、untilです。
doは厳密にはループキーワードではありませんが、ループ構文の重要な一部です。
どのオプションがコマンド ls -l を実行して出力を返しますか?
$(ls -l) の構文は括弧内のコマンドを実行し、出力を置換します。例えば:
echo "Today is $(date +%F)"
1番目のオプションはシングルクォート ' を使用しています。これは展開を防ぎ、'$(date +%F)' は単に文字列 $(date +%F) を出力します。
バッククォート(`ls -l`)によるコマンド実行は依然サポートされていますが、最近は一部の文脈ではアンチパターンとされています。より読みやすく、シェルのバージョンや種類に一貫性を持たせるために $(command) の使用が推奨されます。
中括弧 ${} は変数展開用で、コマンド置換には使われません。
% 文字はコマンド置換には使用されません。
エラー出力を標準出力に結合するためには、どの演算子を使用しますか?
2>&1 演算子は、標準エラー出力(ファイル記述子2)を標準出力(ファイル記述子1)にリダイレクトします。これは、通常の出力と同じストリームにエラーメッセージをキャプチャするのに役立ちます。
私のBashクイズで混乱しましたか?
コメントで教えてください!
補足資料
Bashスキルをブラッシュアップするための以下のリソースをご覧ください: