Bashの便利な機能とか

Bashの知ってると便利な機能(Bash関係無いのも含まれてます)

シェルスクリプト内でコマンドのエラーで実行を中断する

「set -e」と書いておくと、任意のコマンドで0以外が返るとスクリプトの実行が中断される

#!/bin/bash

set -e

echo a

# 0以外の値を返す
false

# ここは実行されない
echo b

シェルスクリプトの中で標準入出力エラーのリダイレクト先を変える

「exec > リダイレクト先」で、コマンド呼出時と同じ要領でスクリプト内でリダイレクト先を変更出来る

#!/bin/bash

# これはコンソールに表示されます
echo "これはコンソールに表示されます"

# 標準出力をファイルにリダイレクト
exec > log.log

# これはファイルに書かれます
echo "これはファイルに書かれます"

# 標準エラーを標準出力と同じ宛先に
exec 2>&1

# エラーメッセージがファイルに出力される
unknown

コンソールから入力した改行区切りのテキストをループでまわす

次のようにすると、「1 2 3」「4 5 6」「7 8 9」が $a にセットされて実行される

while read a; do
  echo "[$a]"
done <<EOS
1 2 3
4 5 6
7 8 9
EOS

プロセス置換(シェル内でファイルを指定する箇所にコマンドを書く)

「<( コマンド )」... コマンドの出力内容をファイルのように扱う
「>( コマンド )」... ファイルへの出力をコマンドの入力として渡す


例えば、次のような方法で2つのリモートサーバのファイルを比較したり

diff <(ssh host1 cat /etc/hosts) <(ssh host2 cat /etc/hosts)

シェルスクリプトの出力をコンソールとファイルの両方に出力させてみたり

#!/bin/bash

echo "これはコンソールにのみ出力されます"

exec > >(tee log.log)

echo "これはコンソールとファイルの両方に出力されます"

grepでパターンに一致する文字だけを出力

「-o」を指定すると、パターンに一致した部分の文字だけが出力される。
例えば、次の様な方法で 192.168.1.1 への接続時のソースアドレスを表示したり

ip route get 192.168.1.1 | egrep -o 'src [0-9.]+' | awk '{print $2}'

テキストの終端N行以外や、先頭N行以外を出力する

「head -n -5」のように、headで負数を指定すると「先頭」〜「下から数えてNー1行目」までが出力される。

ls -l | head -n -5

同じように「tail -n +5」のように、tailで正数を指定すると、「N行目」から「終端」までが出力される。

ls -l | tail -n +5

数字を指定したときの意味が「N−1」だったりそのまま「N」だったりして判りにくいので「head -n -5」は「終端N行以外が出力」と覚えるといいのかもしれない。


sed '3,5d'」のように指定すると、3行目から5行目まで以外が出力される(3〜5行目が削除される)。

ls -1 | sed '3,5d'


sed --quiet '3,5p'」のように指定すると、3行目から5行目までが出力される(headとtailを組み合わせた方が効率的に処理されそう)。

ls -1 | sed --quiet '3,5p'