Bash if…else ステートメントを使用する

文字列比較で数値演算子を使用すると、Bash のブランチで間違ったパスが実行されることがよくあります-eqまたは、変数が引用符で囲まれていない場合。バッシュに切り替える[[ ]]正しい演算子を使用してテストすると、これらの論理エラーが修正され、スクリプトの保守が容易になります。

ステップ 1:新しいスクリプトを作成し、最新の Bash テスト構文を使用して最小限の条件を追加します。[[ ]]。この形式では、偶発的なグロブ展開や単語の分割が回避され、単一括弧と比較して予期しない動作が軽減されます。

#!/usr/bin/env bash
set -euo pipefail

read -r -p "Enter a value: " val

if [[ "$val" == "admin" ]]; then
  echo "Welcome, admin."
else
  echo "Access limited."
fi

ステップ 2:文字列を次と比較します==または!=。変数を引用符で囲んで、空の値やスペースがテストを中断しないようにします。これにより、引用符で囲まれていない展開によって引き起こされる意図しない一致が防止されます。

user="alice"
target="alice"

if [[ "$user" == "$target" ]]; then
  echo "Usernames match."
else
  echo "Usernames differ."
fi

ステップ 3:内部の整数には数値演算子を使用します[[ ]]:-eq-ne-gt-ge-lt-le。これらは数値のみを操作し、辞書編集的な比較を回避します。

read -r -p "Enter a number: " n

if [[ "$n" -gt 10 ]]; then
  echo "Greater than 10."
elif [[ "$n" -eq 10 ]]; then
  echo "Equal to 10."
else
  echo "Less than 10."
fi

ステップ 4:ファイルテスト演算子を使用してファイルをチェックします。これらは、外部コマンドを実行せずにファイルシステムの状態に基づいて分岐するのに役立ちます。

  • -f path: 通常のファイルが存在します。
  • -d path: ディレクトリが存在します。
  • -e path: パスが存在します (任意のタイプ)。
  • -x path: 実行ファイルが存在します。
  • -r path/-w path:読み取り可能/書き込み可能。
path="./data.txt"

if [[ -f "$path" ]]; then
  echo "File exists."
else
  echo "Creating file..."
  : > "$path"
fi

ステップ5:条件を組み合わせる&&(そして)、||(または)、および!(ない)。明確にし、正しい優先順位を得るために、括弧でグループ化します。

こちらもお読みください:Bash および GPT ツールを使用して Linux タスクを自動化する

file="./report.log"
size=5

# True when the file exists AND size is at least 5
if [[ -f "$file" ]] && [[ "$size" -ge 5 ]]; then
  echo "Process report."
fi

# True when user is admin OR staff
role="staff"
if [[ "$role" == "admin" || "$role" == "staff" ]]; then
  echo "Privileged."
fi

# Negation: path exists but is not a directory
if [[ -e "$file" && ! -d "$file" ]]; then
  echo "Path is not a directory."
fi

ステップ6:使用elifショートチェックに。 1 つの条件が true になると、以降の分岐はスキップされるため、評価が高速化され、不要なコマンドが減ります。

status="warning"

if [[ "$status" == "error" ]]; then
  echo "Exit immediately."
  exit 1
elif [[ "$status" == "warning" ]]; then
  echo "Log and continue."
else
  echo "All good."
fi

方法 2: 整数を比較する(( ))算術評価

ステップ 1:数値ロジックには算術コンテキストを使用します。内部(( ))、数学のような比較を書くことができます (<>==) 変数を引用符で囲まずに。これは、整数のみのチェックでは簡潔かつ高速です。

a=12 b=8

if (( a > b )); then
  echo "a is larger."
elif (( a == b )); then
  echo "Equal."
else
  echo "b is larger."
fi

ステップ 2:ブール演算子を算術コンテキストで直接結合します。これにより、複数の数値条件を評価する際の定型文が削減されます。

x=7 y=3 z=10

if (( (x > y) && (z >= 10) )); then
  echo "Threshold met."
fi

ステップ 3:入力を検証します。算術コンテキストでは、数値以外の値をゼロとして扱います。入力が数値以外の可能性がある場合は、正規表現テストで保護します。[[ ]]評価する前に。

read -r n
if [[ "$n" =~ ^-?[0-9]+$ ]] && (( n >= 0 )); then
  echo "Non-negative integer."
else
  echo "Invalid number."
fi

方法 3: POSIX ポータブルを使用する[ ]より広範なシェル互換性のために

ステップ 1:Bash 以外のシェルをターゲットにする場合は、単一の括弧を使用することを推奨します (例:/bin/sh)。覚えておいてください[はコマンドです。スペースと引用符が必要です。

#!/bin/sh

a="hello"
b="hello"

if [ "$a" = "$b" ]; then
  echo "Match."
else
  echo "No match."
fi

ステップ 2:整数には数値演算子を使用し、単語の分割を防ぐために変数を引用符で囲みます。これにより、変数が空であるかスペースが含まれている場合のバグを回避できます。

a=5
b=30

if [ "$a" -lt "$b" ]; then
  echo "a is less than b."
fi

ステップ 3:辞書編集上の文字列比較を行う場合<または>、リダイレクトを防ぐために演算子をエスケープします。多くの間違いはこれを忘れることから起こります。

x="apple" y="banana"

if [ "$x" < "$y" ]; then
  echo "apple comes before banana."
fi

ステップ 4:と同じ方法でファイル テストを使用します。[[ ]]ただし、エッジケースを避けるために、すべてを引用符で囲んでください。

file="./cfg.ini"
if [ -r "$file" ] && [ -w "$file" ]; then
  echo "Config is readable and writable."
fi

方法 4: 長いチェーンを次のものに置き換えます。case値ベースの分岐の場合

ステップ 1:使用case単一の変数に対する複数の等価性チェックを簡素化します。これによりネストが減少しますifをブロックし、パターン照合時の読みやすさと速度を向上させます。

read -r -p "Enter mode (start|stop|status): " mode

case "$mode" in
  start)  echo "Starting...";;
  stop)   echo "Stopping...";;
  status) echo "Service is running.";;
  *)      echo "Unknown mode."; exit 1;;
esac

ステップ 2:複数のパターンを簡単に一致させます。これにより、ロジックがコンパクトに保たれ、変数の比較を繰り返すことがなくなります。

level="warn"

case "$level" in
  error|err)  echo "Exit with failure."; exit 1;;
  warn|warning) echo "Log warning.";;

  info|debug) echo "Proceed normally.";;
  *)          echo "Unrecognized level.";;
esac

方法 5: 複数の条件を正しくテストし、失敗をデバッグする

ステップ 1:真理値表を反映するためにブール論理をグループ化します。たとえば、「Z または X と Y の両方が必要」は次のようになります。if [[ "$Z" == "TRUE" || ( "$X" == "TRUE" && "$Y" == "TRUE" ) ]]。括弧は優先順位を明確にし、微妙なバグを防ぎます。

X="TRUE" Y="FALSE" Z="TRUE"

if [[ "$Z" == "TRUE" || ( "$X" == "TRUE" && "$Y" == "TRUE" ) ]]; then
  echo "Conditions met."
else
  echo "Conditions not met."
fi

ステップ 2:適切な演算子を選択してください。使用==文字列と-eq整数の場合。それらを混合すると、不正な分岐が発生します (例: string と-eq常に失敗します)。

ステップ 3:テストでは、特に単一括弧を使用して変数展開を引用符で囲みます。クォートすると、変数が空の場合のクラッシュが回避され、ファイルシステム エントリに対するワイルドカード拡張が防止されます。

ステップ 4:結果が間違っていると思われる場合はロジックをトレースします。 xtrace を有効にすると、Bash が評価するときに展開された各コマンドと条件が表示されます。

#!/usr/bin/env bash
set -x  # turn on trace
# ... your conditionals here ...
set +x  # turn off trace

ステップ5:スクリプトの一貫性と読みやすさを維持します。本体の下をインデントしますthen/else、括弧の周りにスペースを残し、ネストを減らすためにエラー分岐の早期終了を優先します。

参考: 一般的なテスト演算子の概要

このクイック リストは、ジョブに適切なオペレーターを選択するのに役立ちます。

  • 文字列:==!=-n var(長さ > 0)、-z var(空の)。
  • 整数:-eq-ne-gt-ge-lt-le;または使用します(( ))<>==
  • ファイル:-f(通常)、-d(ディレクトリ)、-e(存在します)、-x(実行可能)、-r(可読)、-w(書き込み可能)。
  • 論理:&&(そして)、||(または)、!(ない);とグループ化する( ... )内部[[ ]]

適切なテスト フォーム、正しい演算子、一貫した引用符を使用すると、Bash の条件文は目的の分岐を毎回実行します。保つ[[ ]]Bash スクリプトの場合は、使用します(( ))数学の場合は、に戻ります[ ]携帯性が必須の場合のみ。

Related Posts