ShellScript
Bash
Linux
bashrc
dotfiles

bashでif文を書くときの [[ ... ]] と [ ... ] の違い


TL;DR

[[ ... ]][ ... ]で全然意味が違うらしいという話

※zshとかbash以外のシェルは管轄外です


結論

[[ ... ]]を使うことにする


発端

.bashrcを整理していたら、どうにも動いていない設定が見つかった

if [ -x $(which colordiff) ]

then
alias diff='colordiff '
else
alias diff='diff '
fi

colordiffコマンドがあればそれをdiffのエイリアスにしようとしていたらしい

たまたま新しい環境でdiffコマンドを叩いた時にエラーになっているのを見つけた

$ diff a b

-bash: colordiff: command not found

すごく残念なことになってる…


調査

以下参考にさせていただきました

GoogleのShell Style Guideにも[[ ... ]]を使う!って書いてあるみたい

恥ずかしながら[testコマンドを表すみたいな内容はなんとなく知っていたが、[[[の違いをちゃんと意識したことはなかった

AND条件&&とOR条件||の書き方なんかは[[ ... ]]の方が直感的にわかりやすく感じた

# [ ... ] でAND/OR

if [ -f ${FILE_PATH_A} ] && [ -f ${FILE_PATH_B} ]
then
# 両方trueのときの処理
...
fi

# [[ ... ] でAND/OR
if [[ -f ${FILE_PATH_A} && -f ${FILE_PATH_B} ]]
then
# 両方trueのときの処理
...
fi

基本bashでしか書く機会ないのでGoogleに乗っかろうと思いつつ、自分以外のコードで出会うときのために細かい違いは抑えておかねばと決意した


修正

先の動いてないコードは以下のように修正した

if [[ -x $(which colordiff) ]]

then
alias diff='colordiff '
else
alias diff='diff '
fi

これで無事にcolordiffなんてない環境でも普通にdiffが動き、colordiffがある環境ではdiffのエイリアスとしてcolordiffが効いてくれるようになってくれた


自戒

なんちゃってdotfilesはちゃんと検証して使おう