rcシェルで空白が含まれるファイル名を正しく扱う
This content is a draft and will not be included in production builds.
Plan 9の rc(1) シェルでは、グロブでファイル名のマッチングを行った場合に正しくスペースを扱える。例えば
% lsa'b c'のようにファイルが存在するディレクトリで、
for(i in *) echo $iを実行すると a と b c の2行が出力される。同様に代入でも同じルールで展開される。
% a=*c% whatis aa='b c'Plan 9のコマンドは、ファイル名にスペースが含まれる場合にクオートで括って出力する習慣がある1。ls(1) の例は上で挙げたが、他にも getflags や venti あたりもこの習慣に従っている。
しかしコマンド出力を ifs で分割する際にはクオートを考慮しない。なので
x=`{ls}whatis xを実行すると x は
- a
- ‘b
- c’
という要素を3つ持ったリストに分割されてしまって、おそらく意図した結果にならない。なので ls の場合は -Q オプションでクオートを無効化する。
nl=''x=`$n{ls -Q}
# 古い場合はこちらifs=$n {x=`{9 ls -Q}}ただし改行文字が正しいファイル名に含まれてしまっている場合は別の対策が必要になる。また、read で1行ずつ読む場合の対策はおそらく無い。
Footnotes
Section titled “Footnotes”-
awkなど古くからあるコマンドでは対応していない場合もある ↩