変数内のスペースを含む値を渡す
スペースを含む文字列を変数に格納してコマンドの引数として渡すときの動作を考える。
例えば以下のように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
\第一線のプログラマーの行動原理を学べる!/