DanLevy.net

クイズ: Bash & Shell マスター

コンピュータとちゃんと話せますか?

この16問のクイズでBashスクリプトスキルをテストしてみましょう!

変数、ループ、条件分岐、文字列操作、関数、そして基本からやや複雑な構文の落とし穴までをカバーします。

シェルスクリプトのスキルを磨く(または証明する)!

Bashで変数はどのように定義されますか?

Bashでの変数宣言は=の前後にスペースを付けません。例えば:

Terminal window
name=Alice

これはname変数に"Alice"を代入します。

注:$nameは変数の参照や値の読み取りに使用されます。

スペースを追加するとシェルがコマンドとして解釈してしまい、変数設定の意図に反します。

また、Bashは大文字小文字を区別するため、nameNAMENameは別の変数になります。

最後に、変数名にスペースやハイフン(-)は使用できません。アンダースコア(_)やcamelCaseを使用してください。

「It’s 🔨 Time!」を出力するコマンドはどれですか?

クォートのエスケープは本当にややこしいですよね。Bash文字列内で他の言語をエスケープする想像してみてください。クォートやアポストロフ、$記号が邪魔になります。🫠

シングルクォート内ではシングルクォートをエスケープする必要があります。'\''というクォート→エスケープ→クォートのシーケンスで出力できます:

It's 🔨 Time!

他の方法もありますが、これは最も一般的な方法です。

このコマンドは何を出力しますか?

Terminal window
echo c{a,b}t

大括弧{}による拡張は、コンマ区切りの値やパターンごとに、文字列コンテキストの複数バージョンを生成します。

ここではc{a,b}tは次のように展開されます:

cat cbt

では、これは何を出力するでしょうか?

Terminal window
price="$100"
echo "Cost: $price"

番号付きの変数は特殊な意味を持ちます。このケースでは、$1はスクリプトまたは関数に渡された最初の引数を保持する特殊な変数です。

REPL環境でスクリプトを実行しているため、引数が存在しないため$1は空になります。残りの文字00はそのまま出力されます。

リテラルの$文字を出力するには、シングルクォートを使用するか、バックスラッシュでエスケープしてください(\):

Terminal window
price="\$100"
echo "Cost: $price"

ここでは何が起こっている?

Terminal window
str="Bark bark"
echo ${str/bark/meow}

${var/pattern/replacement} 構文は、pattern の最初の出現を replacement で置換します。ここでの出力は:

Bark meow

これは大文字小文字を区別します。barkBark の両方を処理するには、${var/[Bb]ark/Bark} のようなパターンを使用するか、置換前に文字列を正規化してください。

すべての出現を置換するには ${var//pattern/replacement} を、 文字列の先頭から置換するには ${var/#pattern/replacement} を、 文字列の末尾から置換するには ${var/%pattern/replacement} を使用します。

Bashで変数の長さを取得する方法は?

${#username}構文はusernameの長さを返します。

例:

Terminal window
username="@justsml"
echo ${#username} # => 8

wcは機能しますが、これは厳密にBashの一部ではありません。

wcユーティリティは古くからあるジョークで「water closet(トイレ)」を指していました。 ジョークです!誰かこれらを読んでいるのでしょうか?

実際にはwcはPosix(およびAT&T Unix時代)からの古いコマンドで、ファイルや入力ストリームの行数・単語数・文字数をカウントします。

ファイルcats.txtが存在する場合、このスクリプトは何を出力しますか?

Terminal window
if [ -e cats.txt]; then
echo "File exists"
else
echo "File does not exist"
fi

閉じ括弧の前のスペースが不足していることに気づけましたか?

Bashはここでは非常に敏感です: 括弧内にスペースが必要です。

スペースの不足により[コマンドが閉じ ]を見逃し、Bashは診断メッセージを表示し、テストを失敗扱いにしてelseブランチに進みます。

正しい構文は次の通りです:

Terminal window
if [ -e example.txt ]; then
echo "File exists"
else
echo "File does not exist"
fi

注: 条件式には**二重括弧[[ ]]**の使用を推奨します。BashFAQを参照してください。

Bashで文字列を比較する方法は?

Terminal window
cat1="Rosie"
cat2="Sunflower"
if [ "$cat1" === "$cat2" ]; then
echo "Same cat"
else
echo "Different cats"
fi

別のテスト構文エラー!

無効な===演算子に気づきましたか?

JavaScriptを思い出したかもしれませんね…

[ ... ]ではBashは診断情報を報告し、条件がfalseになるためelse分岐でDifferent catsを出力します。Bashでは等価比較に=または==を使用してください。

このスクリプトは何を出力しますか?

Terminal window
function greet () {
echo "$1"
}
greet Hi Dan

Bashの関数は引数を受け取ることができます。$1変数は関数に渡された最初の引数を保持します。

覚えておきましょう。$0はスクリプト名、$1は最初の引数、$2は2番目の引数であり、スペースで引数が区切られます。したがって、greet Hi Dan"Hi"を最初の引数として渡します。"Hi Dan"を単一の引数として渡すには、クォートが必要です:greet "Hi Dan"

コマンドの出力を次のコマンドの入力に接続する演算子は何ですか?

パイプ演算子|は、1つのコマンドの出力を別のコマンドの入力に接続します。例えば:

Terminal window
echo "Mr. Levy 👨🏻‍🔬" | wc -m
# => 14

Bashで算術はどのように扱いますか?

(( ))の構文はBashで整数算術を実行します。

簡単な計算に使用できます:

Terminal window
((result = 2 + 2))
echo $result # => 4

条件式にも利用可能です:

Terminal window
if (( 2 > 1 )); then
echo "2 is greater than 1"
fi

浮動小数点演算が必要な場合は、bcawkの利用を検討してください。

これらのうち、10と0.5を掛けて5を出力するのはどれですか?

(( ))の構文は整数算術のみを実行します。小数点を含む浮動小数点計算はサポートされていません!

Bashは(驚くべきことに)組み込みの浮動小数点算術サポートを持っていません。

最も一般的な解決策は、GNUユーティリティbcawkを使うことです。

このスクリプトで:はどのような働きをするか?

Terminal window
rosie="Bad cat, good cat"
echo ${rosie:9}

${var:offset}という構文は、offsetから始まる部分文字列を抽出します。ここでは、出力は次のようになります:

good cat

特定の長さの部分文字列を抽出するには${var:offset:length}を使用します。

文字列の末尾から抽出するには${var: -offset}を使います。(-の前にスペースがあることに注意!)

Bashでルーピングのキーワードでないのはどれですか?❌

eachはBashのループキーワードではありません。主なループキーワードはforwhileuntilです。

doは厳密にはループキーワードではありませんが、ループ構文の重要な一部です。

どのオプションがコマンド ls -l を実行して出力を返しますか?

$(ls -l) の構文は括弧内のコマンドを実行し、出力を置換します。例えば:

Terminal window
echo "Today is $(date +%F)"
# => Today is 2029-12-31

1番目のオプションはシングルクォート ' を使用しています。これは展開を防ぎ、'$(date +%F)' は単に文字列 $(date +%F) を出力します。

バッククォート(`ls -l`)によるコマンド実行は依然サポートされていますが、最近は一部の文脈ではアンチパターンとされています。より読みやすく、シェルのバージョンや種類に一貫性を持たせるために $(command) の使用が推奨されます。

中括弧 ${} は変数展開用で、コマンド置換には使われません。

% 文字はコマンド置換には使用されません。

エラー出力を標準出力に結合するためには、どの演算子を使用しますか?

2>&1 演算子は、標準エラー出力(ファイル記述子2)を標準出力(ファイル記述子1)にリダイレクトします。これは、通常の出力と同じストリームにエラーメッセージをキャプチャするのに役立ちます。

私のBashクイズで混乱しましたか?

コメントで教えてください!

補足資料

Bashスキルをブラッシュアップするための以下のリソースをご覧ください: