変数内のスペースを含む値を渡す
スペースを含む文字列を変数に格納してコマンドの引数として渡すときの動作を考える。
例えば以下のようにfiles変数にa.txtとb.txtを格納してlsコマンドに渡すとする。
$ files="a.txt b.txt"
$ ls $files
シェルやシェルスクリプトでは変数は展開されて実行されるため、イメージとしては以下のようになる。
$ ls a.txt b.txt
ところがシェルによって動作が異なる。
bashの場合
bashでは展開された状態で動作する。
例えば上記lsコマンドの例では以下のように正常動作する。
[bash]
$ files="a.txt b.txt"
$ ls $files
a.txt  b.txt
上記ではlsコマンドにa.txtとb.txtの2引数を渡した状態となるため、a.txtとb.txtが存在する場合はそれぞれのファイルが表示される。
zshの場合
zshではスペースを含めた文字列を1つの引数として動作する。
[zsh]
$ files="a.txt b.txt"
$ ls $files
ls: cannot access 'a.txt b.txt': No such file or directory
上記例では"a.txt b.txt"という文字列をlsコマンドの1つの引数として渡しているため、a.txt b.txtというファイルが存在しないというエラーが表示される。
SH_WORD_SPLIT
zshでbashと同じようにスペースを含む文字列を展開して複数の引数として扱いたい場合はSH_WORD_SPLITを設定する。
[zsh]
$ setopt SH_WORD_SPLIT
$ files="a.txt b.txt"
$ ls $files
a.txt  b.txt
上記例のようにSH_WORD_SPLITを設定すると、zshでもbashと同じようにスペースを含む文字列を展開して複数の引数として扱う。
SH_WORD_SPLITの解除
SH_WORD_SPLITを解除するにはunsetoptコマンドを実行する。
$ unsetopt SH_WORD_SPLIT
ダブルクオートで囲った場合
setopt SH_WORD_SPLITを設定している場合でもダブルクオートで囲むと1つの引数として扱われる。
$ setopt SH_WORD_SPLIT
$ files="a.txt b.txt"
$ ls "$files"
ls: cannot access 'a.txt b.txt': No such file or directory
\第一線のプログラマーの行動原理を学べる!/
