logo
Published on

Bash 引数としての複数行、一行、配列、ダブルクウォートの挙動の比較

Authors

コマンドラインのBash言語において、引数としての複数行、一行、配列、ダブルクウォートの挙動の比較を行いました。

rmコマンドを例に試してみましょう。


$ \ls -1
1.txt
2.txt
3.txt

$ rm "$( \ls -1 )"
rm: cannot remove '1.txt'$'\n''2.txt'$'\n''3.txt': No such file or directory

$ rm $( \ls -1 )

$ rm $( \ls -1 | ruby -e "puts STDIN.read.gsub(/\n/, \"\s\")" )

$ rm ( $( \ls -1 ) )
bash: syntax error near unexpected token `$( \ls -1 )'

よくあるエラー、間違いと正答例

よくしがちな間違いと正答例をまとめてみました。

rm "$$( \ls -1 )"
rm "1.txt 2.txt 3.txt"

rm 1.txt 2.txt 3.txtであればすべてのファイルが消せたことになるわけですね。

この1つ目はよくある間違いですね。ダブルクウォートで囲ってしまうと一つの引数の扱いになります。

rm $$( \ls -1 )
rm 1.txt 2.txt 3.txt

2つ目は、一般的な正答例です。ダブルクウォートで囲まないのがポイント。

rm $$( \ls -1 | ruby -e "puts STDIN.read.gsub(/\n/, \"\s\")" )
rm $$( printf "\n1.txt\n2.txt\n3.txt\n" )
rm 1.txt 2.txt 3.txt

3つ目は、複数行の出力を置換して一行にしています。渡す引数は複数行でも一行でもよい、つまり、空白スペース区切りでも改行区切りでもよい、ということになります。ただし、いずれにしても引数をダブルクウォートで囲むと一つの引数の扱いになりエラーとなります。

rm ( $$( \ls -1 ) )
rm (1.txt 2.txt 3.txt)

4つ目は配列を渡してみました。配列は処理対象じゃないのでエラーになりますね。引数に配列を渡して処理することもたまーにありますので、そういう場合はダブルクウォートなしのカッコ囲みでやってやるとよいでしょう。