BruceBarnettのUNIXShellQuote Tutorialは素晴らしいものであり、BashFAQ /落とし穴/単語分割の記事にはたくさんの役立つヒントがあります。簡単な要約:
引用符で囲まれていない文字列にはほとんどの文字を含めることができますが、すべて(改行など)ではなく、それらの多く(スペースを含む)をエスケープする必要があります。それらを使用しないでください-誘惑に陥った場合、スクリプトを変更した誰かが、必要になったときに引用符を含めるのを忘れていることに気付くかもしれません。
一重引用符で囲まれた文字列には、NULや改行を含むほとんどの文字を含めることができますが、一重引用符は含めることができないため、単純な値の場合にのみ役立ちます。
バックティックはコマンド用です。シェルがをサポートしていない場合にのみ使用してください$()
。例:
current_dir=`pwd` # BAD! Don't do this!
割り当ての右側が引用符で囲まれていない場合、シェルはそのコマンドで単語分割を実行するため、このコマンドは不適切です。空白は視覚的に確認するのが難しいため、再現が難しいバグにつながることがよくあります。コマンドを引用するには、二重引用符を使用する必要があります。
current_dir="$(pwd)" # OK, but loses newlines at EOF
EOFの改行は特に注意が必要です。たとえば、1つの文字を追加し、それを削除することができます
# Works for some commands, but not pwd
current_dirx="$(pwd; echo x)"
current_dir="${current_dirx%x}"
printf %s "$current_dir"
、ただし、一部のコマンド(など)は出力の最後に改行を追加するため、追加の問題がありますpwd
。そのため、それも削除する必要がある場合があります。
# Works for some commands, including pwd
current_dirx="$(pwd; echo x)"
current_dir="${current_dirx%$'\nx'}"
printf %s "$current_dir"
二重引用符には任意の文字を含めることができますが(Try echo -ne "\0" | wc -c
)、変数にNUL文字を含めることはできないことに注意してください。
ANSI-C引用符には、 NUL(Tryの任意の文字を含めることができecho -ne $'\0' | wc -c
、特殊文字の操作を容易にする便利なエスケープコードを提供します。
printf %s $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'
printf %q $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'
touch -- $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'
rm -- $'--$`!*@\a\b\E\f\r\t\v\\\'"\360\240\202\211 \n'