bashスクリプトでset -uしているときの unbound variable を回避する


このエントリーをはてなブックマークに追加

bashスクリプトの定番テクニックで、set -uを冒頭に書いておくことで、未定義の変数をうっかり使った時点でスクリプトを終了させるようにする、というものがあります( 参考 )。しかし、PATHやPYTHONPATHにパスを追加するときに困ることがあります。例えば、以下のようにPYTHONPATHにパスを追加するスクリプト

#!/bin/bash
set -u

export PYTHONPATH=/path/to/somewhere:${PYTHONPATH}

を実行するとき、もしPYTHONPATHが未set状態なら、

bash_undefined.sh: line 4: PYTHONPATH: unbound variable

というエラーが出てしまいます。

回避方法はいくつかありそうです。

-vを使う方法

bash 4.2から、-vを使うことで変数がsetされているかどうかを確認できるようになったそうです ( shell - How to check if a variable is set in Bash - Stack Overflow )。これを使うと以下のようにかけます。

#!/bin/bash
set -u

PATH1=/path/to/somewhere
if [[ -v PYTHONPATH ]]; then
    export PYTHONPATH=${PATH1}:${PYTHONPATH}
else
    export PYTHONPATH=${PATH1}
fi

一時的にset -uをやめる方法

set +uset -uで挟んだ部分だけ未定義の変数が使えるようになります。

#!/bin/bash
set -u

set +u
export PYTHONPATH=/path/to/somewhere:${PYTHONPATH}
set -u

Shell Parameter Expansionを使う方法

Assigning default values to shell variables with a single command in bash - Stack Overflow によると、例えば${VARIABLE:-default}と書くとき、もし変数${VARIABLE}が未定義ならかわりにdefaultという文字列を使うという意味になります。これは Shell Parameter Expansion というテクニックだそうです。

いまの例だと、PYTHONPATHという変数が未定義な場合は空文字列で代替したいので、以下のように書けます。

#!/bin/bash
set -u

export PYTHONPATH=/path/to/somewhere:${PYTHONPATH:-}