Mobile Factory Tech Blog

技術好きな方へ!モバイルファクトリーのエンジニアたちが楽しい技術話をお届けします!

>/dev/null 2>&1 しなくても黙ってくれるコマンドオプション3選

こんにちは。駅奪取チームエンジニアのid:dorapon2000です。

よくシェルスクリプトのIF文に >/dev/null 2>&1 を書いて条件文とすることはありませんか。実行結果の成否をIF条件として利用したいのであって実際に出力したいわけではないケースです。

実は身近なコマンドでもオプションで出力を抑制できます。3つ紹介します。

検証環境

  • Ubuntu 16.04
  • bash 4.3.48

grep --quiet

特定の文字列を含むときにだけif文を実行します。

まず、>/dev/null 2>&1 を使う書き方。grepに引っかかると0を返し(True)、grepに引っかからないと1を返します(False)。

if cat /var/log/syslog | grep "Error" >/dev/null 2>&1; then
    echo 'Found'
fi

--quiet オプションを使うことで、出力を抑制してくれます。

if cat /var/log/syslog | grep --quiet "Error"; then
    echo 'Found'
fi

# -q でも可
if cat /var/log/syslog | grep -q "Error"; then
    echo 'Found'
fi

以下のサイトでは、--quiet を使うことで高速化もするという嬉しい情報もあります。

シェルスクリプトでファイルに特定の文字が含まれているかどうかを高速に判定する方法 | ゲンゾウ用ポストイット

git diff --quiet

git差分があるときにだけif文を実行します。

まず、>/dev/null 2>&1 を使う書き方。git diff は差分のありなしに関わらず正常終了の0を返すため、ifで使うには --exit-code オプションが必要です。差分があるときに1を(False)、差分がないときに0を返すようになります(True)

# ① --exit-code を使う場合
if ! git diff --exit-code >/dev/null 2>&1; then
    echo 'Diff'
fi

あるいは --exit-code を使わず以下のように書く人もいるでしょう。

# ② [を使う
if [ `git diff | wc -l` -gt 0 ]; then
    echo 'Diff'
fi

# ③ bash構文を使う
if [[ `git diff | wc -l` > 0 ]]; then
    echo 'Diff'
fi

さて、git diffにも --quiet オプションがあります。さらに --quiet オプションは暗黙的に --exit-code オプションを利用しており、一石二鳥です。

if ! git diff --quiet;
    then echo 'Diff';
fi

非常にスッキリしましたね!

apt list -qq

aptで特定のパッケージをインストールしていなかったらインストールしたいことは多いです。

まずは、前述した grep --quiet を使うやり方から。

if apt list --installed sl | grep -q sl ; then
    sudo apt install sl -y
fi

これでいいじゃん!ですが、aptの -qq オプションでも同じことができるため紹介します。

aptの -qq オプションは --quiet オプションをより強力にしたもので、進捗情報を消してくれます。ログ出力のためにあるオプションのようです。完全に出力を消すものではありません。

$ apt list --installed sl
一覧表示... 完了  # <-- これが消える
sl/xenial,now 3.03-17build1 amd64 [インストール済み]

$ apt list -qq --installed sl
sl/xenial,now 3.03-17build1 amd64 [インストール済み]

したがって、最初のif文は以下のように書き換える事ができます。grep ^ でパイプで渡される出力が空かどうかを判定します。

if ! apt list -qq --installed sl | grep -q ^; then
    sudo apt install sl -y
fi

aptの警告について

上記例を実行すると警告が表示されます。

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

書かれているとおりで、aptは出力フォーマットが安定しているわけではないため、出力結果を加工するスクリプトはあまりよろしくないようです。 可能なら別のコマンドを利用したほうがよく、apt list --installed に関しては dpkg -l で代替できます。

if ! dpkg -l | grep -q sl; then
    sudo apt install sl -y
fi