長い間私を悩ませてきたこの難問を解決する時がきました...
私は時々これに会っていて、これが行く方法だと思っていました:
$(comm "$(arg)")
そして、私の見解は経験に強く支えられていると思いました。でも、もうよくわかりません。 Shellcheck も決心できません。それは両方です:
"$(dirname $0)"/stop.bash
^-- SC2086: Double quote to prevent globbing and Word splitting.
そして:
$(dirname "$0")/stop.bash
^-- SC2046: Quote this to prevent Word splitting.
背後にあるロジックは何ですか?
(これはShellcheckバージョン0.4.4です。)
"$(somecmd "$file")"
を使用する必要があります。
引用符がないと、スペースのあるパスはsomecmd
への引数で分割され、間違ったファイルをターゲットにします。だからあなたは内側に引用符が必要です。
somecmd
の出力にスペースが含まれている場合も分割が発生するため、コマンド置換全体の外側に引用符が必要です。
コマンド置換内の引用符は、それ以外の引用符には影響しません。Bash独自のリファレンスマニュアルは、これについてあまり明確ではありませんが、- BashGuideは明示的にそれについて言及しています 。 POSIXのテキスト も必要です。これは、 "有効なシェルスクリプト"が$(...)
内で許可されているためです:
$(command)
フォームでは、左括弧に続く対応する右括弧までのすべての文字がコマンドを構成します。コマンドに有効なシェルスクリプトを使用できますが、指定されていない結果を生成するリダイレクトのみで構成されるスクリプトは除きます。
例:
_$ file="./space here/foo"
_
a。引用符なし、dirname
は_./space
_と_here/foo
_の両方を処理します:
_$ printf "<%s>\n" $(dirname $file)
<.>
<here>
_
b。内部の引用、dirname
は_./space here/foo
_を処理し、_./space here
_を与えます。これは2つに分割されます。
_$ printf "<%s>\n" $(dirname "$file")
<./space>
<here>
_
c。外側の引用、dirname
は_./space
_と_here/foo
_の両方を処理し、別々の行に出力しますが、2つの行が1つの引数を形成します:
_$ printf "<%s>\n" "$(dirname $file)"
<.
here>
_
d。内部と外部の両方を引用し、これは正しい答えを与えます:
_$ printf "<%s>\n" "$(dirname "$file")"
<./space here>
_
(もしdirname
が最初の引数だけを処理するならもっと単純だったかもしれませんが、それはケースaとcの違いを示さないでしょう。)
dirname
(およびその他の可能性がある)では、_--
_も追加する必要があることに注意してください。ダッシュで始まる場合にファイル名がオプションとして使用されないようにするため、"$(dirname -- "$file")"
。