プログラミング

Bash 変数がTrue(false)かどうかをifする

僕はBashの関数において、「オプション」を実装するのが好きではありません。オプション実装したことがある方わかると思いますが、60行くらい必要ですからね、まぁ数にもよりますが。
じゃあどうしても関数内でオプション的なものが必要になったときはどうしてるのか、というと、はい、ローカル変数を使ってます。

hoge(){

  # and more.. 

  if ( [[ "${show_hr}" == true ]] || [[ "${show_hr}" == false ]] ) && "${show_hr}" ; 
  then  
    horizonal_line
  fi 

  # and more..

}

上記のような関数を実行する際に、ローカル変数show_hrを渡すと、それが関数内で使われます。この例では、show_hr=true hogeといったように実行してやれば、ifブロックのコマンドが実行されることになります。falseを渡したければshow_hr= hogeshow_hr=false hoge、値を渡したければshow_hr=value hogeですね。

上記のifブロックでは、show_hrの型がboolean;真偽値かどうか軽くバリデーションしています。このバリデーションがないと、例えばshow_hrの値が真偽値以外、foobarだったとき、not found command: foobar的なエラーになります。なので、まぁバリデーションがいらないなら以下のような書き方でおkです。僕なりに考えた結果、上記の書き方がよさげでおすすめ、という感じですね。

hoge(){

  # and more.. 

  if "${show_hr}" ; 
  then  
    horizonal_line
  fi 

  # and more..

}

Javaとか型宣言系言語の良さがわかる気がしますね。配列は接尾辞にsをつけて複数形にするとかできますけど、真偽値っていまいちこうしようみたいな決まりってないですよね。show_hr_booleanとか長いしね。Rubyみたいにshow_hr?みたいにしてみるのも悪くないのかな。んー。

追記

ちなみにですが。trueの場合は文字列でもtrueになりますが、falseの場合は文字列だとtrueになりますね。jsonなどから真偽値を取得する場合は文字列で取得することもあるかと思います。

そういう場合はevalしてやるとよいですね。

{
  "waked_up_once": "true"
}
if eval "$( cat "${CONFIG_JSON}" | parsejson '["waked_up_once"]' )" ; 
then 
  echo y 
fi