Bashプログラミング
 Computer >> コンピューター >  >> プログラミング >> Bashプログラミング

Bashの制御演算子(&& と ||)を使いこなす:コマンド連結とエラー処理の基本

コマンドライン上で複数のコマンドを順番につなげて実行する、シンプルな複合コマンドは非常によく使われます。このようなコマンドはセミコロン(;)で区切られます。セミコロンは「コマンドの終わり」を定義する役割を持ちます。1行にシェルコマンドの連続を記述するには、各コマンドをセミコロンで区切るだけです。

command1 ; command2 ; command3 ; command4

最後のコマンドの末尾にセミコロンを付ける必要はありません。Enterキーを押すことで最後のコマンドの終了が暗黙的に示されるからです。ただし、見た目の一貫性を保つために付けても問題ありません。

エラーが発生したらどうなる?

上記のように書けば、エラーさえ発生しなければすべてのコマンドは問題なく実行されます。しかし、途中でエラーが起きた場合はどうなるでしょうか。そこで活躍するのが、Bashに組み込まれた制御演算子 &&|| です。これら2つの制御演算子を使うと、簡単なフロー制御が可能になり、コードの実行順序を柔軟に変更できます。ちなみに、セミコロンや改行文字もBashの制御演算子として扱われます。

&& 演算子:「成功したら次を実行」

&& 演算子は「command1 が成功した場合のみ command2 を実行する」という意味です。command1 が何らかの理由で失敗すれば、command2 は実行されません。構文は以下の通りです。

command1 && command2

これが機能するのは、すべてのコマンドが「正常に完了したか」「実行中に失敗したか」を示すリターンコード(RC)をシェルへ返すためです。慣例として、リターンコードが 0(ゼロ)なら成功、正の数なら何らかの失敗を意味します。一部のシステム管理ツールは失敗時に単純に 1 を返すだけですが、多くのツールは失敗の種類を示すために別の正の数値コードを使用します。

$? 変数でリターンコードを確認する

Bashシェルの $? 変数は、スクリプト内でも、コマンドリストの次のコマンドでも、さらにはシステム管理者が直接ターミナルででも、非常に簡単に確認できます。実際に試してみましょう。シンプルなコマンドを実行し、直後にRCをチェックします。$? は常に「直前に実行されたコマンド」の結果を保持することに注意してください。

[student@studentvm1 ~]$ ll ; echo "RC = $?"
total 284
-rw-rw-r--  1 student student   130 Sep 15 16:21 ascii-program.sh
drwxrwxr-x  2 student student  4096 Nov 10 11:09 bin
<snip>
drwxr-xr-x. 2 student student  4096 Aug 18 10:21 Videos
RC = 0
[student@studentvm1 ~]$

この場合RCは 0 なので、コマンドが正常に完了したことを意味します。今度は、アクセス権限のないディレクトリに対して同じコマンドを実行してみます。

[student@studentvm1 ~]$ ll /root ; echo "RC = $?"
ls: cannot open directory '/root': Permission denied
RC = 2
[student@studentvm1 ~]$

このRC「2」の意味は、ls コマンドのmanページで確認できます。

&& 演算子の実践例

それでは、&& 制御演算子をコマンドラインプログラムで使う例を見てみましょう。まずはシンプルなところから始めます。「新しいディレクトリを作成し、それが成功したらその中に新しいファイルを作成する」という処理です。

作業用のディレクトリが必要なので、まずホームディレクトリにテスト用の一時ディレクトリを作成します。

[student@studentvm1 ~]$ cd ; mkdir testdir

次に、作成したばかりで空のはずの ~/testdir の中に新しいディレクトリを作り、その新しいディレクトリの中に空のファイルを作成します。以下のコマンドでこれらの処理が実行できます。

[student@studentvm1 ~]$ mkdir ~/testdir/testdir2 && touch ~/testdir/testdir2/testfile1
[student@studentvm1 ~]$ ll ~/testdir/testdir2/
total 0
-rw-rw-r-- 1 student student 0 Nov 12 14:13 testfile1
[student@studentvm1 ~]$

testdir ディレクトリにアクセスでき書き込み可能であるため、すべてが期待どおりに動作しました。ここで、testdir のパーミッションを変更して、ユーザー student からアクセスできないようにしてみます。

[student@studentvm1 ~]$ chmod 076 testdir ; ll | grep testdir
d---rwxrw-. 3 student student  4096 Nov 12 14:13 testdir
[student@studentvm1 ~]$

詳細リスト(ll)の後ろに grep コマンドを組み合わせることで、testdir のエントリだけを表示しています。ユーザー studenttestdir ディレクトリにアクセスできなくなっていることが分かります。では、先ほどとほぼ同じコマンドを、今度は testdir 内に別名のディレクトリを作成するように変えて実行してみましょう。

[student@studentvm1 ~]$ mkdir ~/testdir/testdir3 && touch ~/testdir/testdir3/testfile1
mkdir: cannot create directory ‘/home/student/testdir/testdir3’: Permission denied
[student@studentvm1 ~]$

エラーメッセージは表示されましたが、&& 制御演算子のおかげで、testdir3 の作成に失敗したため touch コマンドは実行されませんでした。この種のコマンドライン上での論理的なフロー制御により、エラーが連鎖して状況を悪化させるのを防ぐことができます。しかし、もう少し複雑なこともできます。

|| 演算子:「失敗したときの処理を追加」

|| 制御演算子を使うと、「最初のコマンドがゼロより大きいリターンコードを返した場合(=失敗した場合)」に実行される別のコマンドを追加できます。

[student@studentvm1 ~]$ mkdir ~/testdir/testdir3 && touch ~/testdir/testdir3/testfile1 || echo "An error occurred while creating the directory."
mkdir: cannot create directory ‘/home/student/testdir/testdir3’: Permission denied
An error occurred while creating the directory.
[student@studentvm1 ~]$ 

この例では、mkdir の失敗を受けて echo コマンドが実行され、エラーメッセージが表示されました。このように || を組み合わせれば、失敗時にユーザーへ通知したり、代替処理を実行したりできます。

制御演算子を使った複合コマンドの一般形

&&|| の両方の制御演算子を使ったフロー制御を含む複合コマンドは、一般的に次のような形式になります。

preceding commands ; command1 && command2 || command3 ; following commands

制御演算子による複合コマンドの前後には、他のコマンドを配置できます。これらのコマンドはフロー制御部分のコマンドと関連していても構いませんが、フロー制御の影響は受けません。つまり、前後のコマンドは、フロー制御の複合コマンド内部で何が起こっても関係なく実行されます。

まとめ

これらのフロー制御演算子を使えば、判断処理を自動化し、問題が発生した際にすぐ気づけるようになるため、コマンドラインでの作業効率が大きく向上します。筆者自身も、コマンドラインで直接使うだけでなく、スクリプトの中でも日常的に利用しています。

なお、検証が終わったらrootユーザーとしてクリーンアップを行い、テスト用ディレクトリとその内容を削除しておきましょう。

[root@studentvm1 ~]# rm -rf /home/student/testdir

あなたはBashの制御演算子をどのように活用していますか?ぜひコメント欄で教えてください。

  1. Linuxコマンド入門:知っておくべき基本のBashコマンドラインヒント集

    Linuxには膨大な数のコマンドが用意されていますが、実際に日常的に使われているのはその一部だけです。この記事では、ターミナルで頻繁に利用されるLinuxコマンドを中心に、初心者でもすぐに活用できる基本的なコマンドラインのヒントをわかりやすく解説します。 コマンドラインを使いこなすための時短テクニック まずは、コマンドライン操作をより快適にするための便利な小技から紹介します。 Tabキーによる自動補完:コマンドやファイル名を途中まで入力したらTabキーを押しましょう。入力した文字列で始まる候補が自動的に表示され、入力の手間とミスを大幅に減らせます。 履歴検索:Ctrl + R を押してキー

  2. Linuxで覚えておきたい10個のコマンド連結演算子と実用例

    Linuxにおける「コマンドの連結(チェーン)」とは、複数のコマンドを1行にまとめ、その間に挟んだ演算子の働きに応じて実行を制御するテクニックです。シェル上で小さなスクリプトを書くのに近い感覚で、ターミナルから直接手軽に実行できます。定型作業の自動化はもちろん、無人で稼働するサーバーをより体系的かつ安定して動作させるうえでも非常に有効です。あわせて読みたい: Awkと正規表現を使ってファイル内のテキストを抽出・フィルタリングする方法本記事では、日常的によく使われるコマンド連結演算子を10個厳選し、簡潔な説明と実際の実行例とともに解説します。これらを使いこなせるようになれば、短くて意味のあるコマ