シェルスクリプトに空白を含むパスを渡した場合の扱い
シェルスクリプト(bash)を書いていて、空白を含むパス(個人的には滅んでほしいが‥)の扱いに苦慮することがあるので、だめなケースとその実行結果も含めてメモしておく。
#! /bin/bash printf "Number of args: %5d\n" $# echo '=== foreach-1("$*")' i=1 for d in "$*" ; do printf "%5d:" ${i} echo " "${d} i=$((${i}+1)) done echo '=== foreach-2("$@")' i=1 for d in "$@" ; do printf "%5d:" ${i} echo " "${d} i=$((${i}+1)) done echo '=== foreach-3($*)' i=1 for d in $* ; do printf "%5d:" ${i} echo " "${d} i=$((${i}+1)) done echo '=== foreach-4($@)' i=1 for d in $@ ; do printf "%5d:" ${i} echo " "${d} i=$((${i}+1)) done echo "=== for" for ((i = 1; i <= $#; ++i)); do printf "%5d:" ${i} eval d2='${'${i}'}' echo " "${d2} done
実行結果。実際に試したのは次の環境。
- MinGW/MSYS on Windows Vista (bash 2.04.0(1)-release)
- OpenSolaris 2009.06 (bash 3.2.25(1)-release)
- Ubuntu 8.04 (bash 3.2.39(1)-release)
- Ubuntu 9.10 (bash 4.0.33(1)-release)
$ ./test.sh a "b c" Number of args: 2 === foreach-1("$*") 1: a b c === foreach-2("$@") 1: a 2: b c === foreach-3($*) 1: a 2: b 3: c === foreach-4($@) 1: a 2: b 3: c === for 1: a 2: b c
一番簡単なのは、「"$@"」と書くやり方。
最後の、for文とevalコマンドで「${1}、${2}、‥」という変数の評価結果を別の変数に入れるというやり方も場合によっては必要になるだろう。