&&(AND) / ||(OR) / !(NOT) / ;(順次実行) / &(バックグラウンド)
| 対応: | 全Linux | |
|---|---|---|
| macOS(2001 Cheetah) | ||
| Bash 1.0(1989) |
『;』(セミコロン)、『&&』(AND)、『||』(OR)、『!』(NOT)はコマンドを連結するための演算子です。コマンドの実行順序や条件分岐をワンライナーで表現できます。終了ステータス(0=成功、非0=失敗)に基づいて動作が決まります。
構文
セミコロン(『;』)は前のコマンドの成否に関わらず次のコマンドを実行します。
コマンド1 ; コマンド2
『&&』はコマンド1が成功(終了ステータス0)したときだけコマンド2を実行します。
コマンド1 && コマンド2
『||』はコマンド1が失敗(終了ステータス非0)したときにコマンド2を実行します。
コマンド1 || コマンド2
『!』はコマンドの終了ステータスを反転させます(0→1、非0→0)。
! コマンド
『&』(シングルアンパサンド)はコマンドをバックグラウンドで実行します。『&&』とは全く別の意味です。
コマンド &
演算子一覧
| 演算子 | 名前 | 概要 |
|---|---|---|
| cmd1 ; cmd2 | セミコロン(順次実行) | cmd1 の成否に関わらず cmd2 を実行します。 |
| cmd1 && cmd2 | AND | cmd1 が成功(終了ステータス0)したときだけ cmd2 を実行します。 |
| cmd1 || cmd2 | OR | cmd1 が失敗(終了ステータス非0)したときに cmd2 を実行します。 |
| ! cmd | NOT | cmd の終了ステータスを反転させます(0→1、非0→0)。 |
| cmd & | バックグラウンド実行 | cmd をバックグラウンドプロセスとして起動します。『&&』とは別物です。 |
サンプルコード
セミコロン(『;』)を使うと、前のコマンドの成否に関わらず次のコマンドを実行します。捜査記録のバックアップとログ記録を続けて実行する例です。
cp kogami_report.txt kogami_report.bak ; echo "バックアップ完了" バックアップ完了
『&&』を使うと、前が成功したときだけ次を実行します。ディレクトリ作成に成功した場合だけ移動します。
mkdir /tmp/case_files && cd /tmp/case_files mkdir /tmp/case_files && cd /tmp/case_files mkdir: /tmp/case_files: File exists
ディレクトリ作成→移動→ファイル生成を一気に行う例です。いずれかが失敗した時点で止まります。
mkdir /tmp/investigation && cd /tmp/investigation && touch crime_coefficient.sh
『||』を使うと、前が失敗したときにフォールバック処理を実行します。ログファイルが存在しなければ作成します。
cat case_report.log || echo "ログファイルが見つかりません。新規作成します。" > case_report.log
コマンドが失敗したらエラーメッセージを表示してスクリプトを終了する定番パターンです。
cp analysis.csv /backup/ || { echo "バックアップ失敗: $?" >&2; exit 1; }
『!』(NOT)を使うと終了ステータスを反転できます。ディレクトリが存在しない場合に処理を行う例です。
! [ -d /tmp/reports ] && mkdir /tmp/reports && echo "ディレクトリを作成しました" ディレクトリを作成しました
『&&』と『||』を組み合わせると、成功時・失敗時それぞれの処理を書けます。
grep "Kogami Shinya" /etc/allowed_users && echo "アクセス許可" || echo "アクセス拒否" Kogami Shinya アクセス許可
crime_coefficient.sh
#!/bin/bash # 犯罪係数チェックスクリプト LOG_FILE="/var/log/psycho_pass/case_report.log" BACKUP_DIR="/backup/investigation" # ログディレクトリが存在しなければ作成 [ -d "$(dirname $LOG_FILE)" ] || mkdir -p "$(dirname $LOG_FILE)" # バックアップディレクトリ作成 → バックアップ → 結果をログに記録 mkdir -p "$BACKUP_DIR" \ && cp "$LOG_FILE" "$BACKUP_DIR/case_report_$(date +%Y%m%d).log" \ && echo "$(date): バックアップ成功" >> "$LOG_FILE" \ || echo "$(date): バックアップ失敗" >> "$LOG_FILE"
概要
『&&』と『||』は終了ステータス($?)に基づいて動作します。終了ステータス 0 は成功、非0(1〜255)は失敗を表します。多くのコマンドは成功時に 0、エラー時に 1 または 2 を返します。
『set -e』を有効にすると、コマンドが失敗した時点でスクリプトが即座に終了します。ただし、『||』の左辺コマンドが失敗しても、『||』があるとシェルが「条件式の一部」と判断して set -e を無視します。意図せずエラーが握りつぶされることがあるため注意が必要です。
『&』(シングルアンパサンド)はコマンドをバックグラウンドプロセスとして起動します。『&&』(ダブルアンパサンド)は AND 演算子です。タイプミスで混同しやすい組み合わせです。
よくあるミス
よくあるミス1: && と & の混同
『&&』(AND)と『&』(バックグラウンド実行)は1文字違いで意味が全く異なります。
cp analysis.csv /backup/ & echo "完了" 完了 [1] 1234
上記は『&』を使っているため、『cp』がバックグラウンドで動きながら即座に『echo』が実行されます。コピーが完了していなくても「完了」と表示されます。『&&』を使って「コピー成功後に完了と表示」したい場合は次のように書きます。
cp analysis.csv /backup/ && echo "完了" 完了
さらに紛らわしいのが末尾に『&』を付けるパターンです。
cmd1 && cmd2 &
これは「(cmd1 && cmd2)をバックグラウンドで実行」と解釈されます。つまり cmd1 が成功したら cmd2 を実行するという AND の連結全体がバックグラウンドになります。
よくあるミス2: set -e 環境下で || を使う落とし穴
『set -e』を設定したスクリプト内で『||』を使うと、左辺が失敗しても set -e によってスクリプトが終了しません(意図通り)。しかし関数呼び出しを『||』の左辺に書いた場合、関数内のエラーも set -e では捕捉されなくなります。
check.sh
#!/bin/bash
set -e
check_file() {
cat /nonexistent/kogami_report.txt
echo "この行は実行されるか?"
}
check_file || echo "ファイルが見つかりませんでした"
echo "スクリプト継続"
修正後は次の通りです。
bash check.sh cat: /nonexistent/kogami_report.txt: No such file or directory この行は実行されるか? スクリプト継続
関数内の『cat』は失敗しているにもかかわらず、『||』があるため set -e が機能せず、関数内の次の行(echo)が実行されてしまいます。さらに echo が成功するため関数全体の終了ステータスが 0 になり、『||』の右辺(「ファイルが見つかりませんでした」)は実行されません。set -e と『||』の組み合わせは直感に反する動作をすることがあるため、十分なテストが必要です。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。