ブログ

シェルスクリプトやコンソール内で複数のコマンドを連続して実行する小技

at_shigehisa.y…
2019年1月8日 13時40分

シェルスクリプトやコンソール内でコマンドを実行させる際、各コマンドを連続して実行させたい場合や、コマンドの終了ステータスによって別のコマンドを実行させたい場合があります。

そこで本ブログでは、制御演算子(リスト演算子)を使ってコマンドを連結させる方法を紹介します。

なお、本ブログではコマンドを2つ使っていますが、複数コマンドの連結も可能です。

制御演算子(リスト演算子) 「;」

コマンド1が終了したらコマンド2を実行させます。コマンドを;で連結すると、コマンド1の終了ステータスに関係なく、コマンド1の実行後にコマンド2が実行されます。

以下の例では、sleepコマンドで1秒間スリープした後、lsコマンドが実行されます。これはsleepコマンドが正常終了した例です。

root@armadillo:~# sleep 1 ; ls -l
total 4
drwxr-xr-x 4 root root 4096 Jan  7 21:48 test_app

次のコマンドはsleepの引数がないためsleepコマンドは異常終了しますが、;でコマンドを連結しているため、lsコマンドが実行されます。

root@armadillo:~# sleep ; ls -l
sleep: missing operand
Try 'sleep --help' for more information.
total 4
drwxr-xr-x 4 root root 4096 Jan  7 21:48 test_app

制御演算子(リスト演算子) 「&」

コマンド1をとコマンド2を並列で実行させます。各コマンドを&で連結すると、各コマンドはバックグラウンドで実行されます。

ブログ記事「Windows Subsystem for LinuxとX Windowの連携」の「4. Xクライアントの起動」に示した実行例では、xeyesやxclockを&で結んで、各コマンドを並列に実行しています。

atmark@PC-0050:~$ xeyes & xclock & gnome-terminal & xcalc & gedit .bashrc &
TAG index

制御演算子(リスト演算子) 「&&」

コマンド1が正常終了した場合のみ、コマンド2が実行されます。

カレントディレクトリにはtest_appディレクトリのみ存在しています。

root@armadillo:~# ls -l
total 4
drwxr-xr-x 4 root root 4096 Jan  7 21:48 test_app

test_appディレクトリにcdコマンドで移動(cdコマンドは正常終了)した後、lsコマンドを実行するとtest_appディレクトリの内容が表示されます。

root@armadillo:~# cd test_app && ls -l
total 20
drwxr-xr-x 2 root root 4096 Jan  7 21:48 atmark
-rw-r--r-- 1 root root  142 Jan  7 16:51 md.js
drwxr-xr-x 5 root root 4096 Jan  7 16:43 node_modules
-rw-r--r-- 1 root root  534 Jan  7 16:43 package-lock.json
-rw-r--r-- 1 root root  270 Jan  7 16:43 package.json

ここで存在しないtest_dataディレクトリにcdコマンドを実行してlsコマンドを実行しても、cd test_dataが異常終了するため、lsコマンドは実行されません。

root@armadillo:~# cd test_data && ls -l
-bash: cd: test_data: No such file or directory

制御演算子(リスト演算子) 「|」

コマンド1の結果をコマンド2へ渡して結果を出力します。

/proc/interruptsには、IRQの割り込み回数が記録されています。

root@armadillo:~# cat /proc/interrupts
           CPU0
 16:     620894       GPC  55 Level     i.MX Timer Tick
 18:       6455       GPC  26 Level     2020000.serial
 29:          0       GPC  80 Level     20bc000.wdog
 35:          0       GPC  19 Level     rtc alarm
 44:          0       GPC  43 Level     2184000.usb
 45:          0       GPC  42 Level     2184200.usb
 46:      32594       GPC 118 Level     2188000.ethernet
 47:          0       GPC 119 Level     2188000.ethernet
 48:      55584       GPC  22 Level     mmc0
 49:         52       GPC  23 Level     mmc1
 50:          3       GPC   5 Level     21c8000.lcdif
 51:          0       GPC  28 Level     21ec000.serial
 52:          0       GPC  30 Level     21f4000.serial
 63:          0  gpio-mxc  10 Edge      SW1
181:          0  gpio-mxc   0 Edge      21ec000.serial
182:          0  gpio-mxc   1 Edge      21ec000.serial
183:          0  gpio-mxc   2 Edge      21ec000.serial

ここで特定の割り込みの回数だけ調べたい場合は、catコマンドとgrepコマンドをパイプで連結します。

以下の例では、mmc割り込みの回数を確認しています。

root@armadillo:~# cat /proc/interrupts | grep mmc*
 48:      55587       GPC  22 Level     mmc0
 49:         52       GPC  23 Level     mmc1

制御演算子(リスト演算子) 「||」

コマンド1が異常終了した場合のみ、コマンド2が実行されます。

カレントディレクトリにはtest_appディレクトリのみ存在しています。

root@armadillo:~# ls -l
drwxr-xr-x 4 root root 4096 Jan  7 21:48 test_app

ここで存在しないtest_dataにcdコマンドを実行するとcdコマンドは異常終了となります。

この状態を受けてtouchコマンドを||で連結すると、test_dataディレクトリが作成されます。

root@armadillo:~# cd test_data || touch test_data
-bash: cd: test_data: No such file or directory
root@armadillo:~# ls -l
total 4
drwxr-xr-x 4 root root 4096 Jan  7 21:48 test_app
-rw-r--r-- 1 root root    0 Jan  7 23:16 test_data