魚のパラメータは、原則として、魚のコマンドに挿入される前にエスケープされます。
mqudsi@freebsd> echo hello > hello\ world.txt
mqudsi@freebsd> file (echo hello world.txt)
hello world.txt: ASCII text
ただし、中括弧の展開の結果は正しくエスケープされません。また、パラメータの前後に引用符を挿入すると展開が中断されるため、手動でエスケープする簡単な方法はありません。
mqudsi@freebsd> echo -n hello\ {1,2,3}.txt\n
hello 1.txt
hello 2.txt
hello 3.txt
ご覧のとおり、最初のパラメーターの後に、 echo
2つの別々の引数hello
と#.txt
が渡され、単語の前に余分なスペースができます。
引数を引用符で囲むと、次のようになります。
mqudsi@freebsd> echo -n "hello\ {1,2,3}.txt\n"
hello\ {1,2,3}.txt\n
エスケープされた引用符を元の文字列に挿入して問題を回避しようとすると(置換後および挿入前に文字列の内容がエスケープされていないという前提で)、引用符が正しくエスケープされ、目的の結果が得られません。
mqudsi@freebsd> echo -n \"hello\ {1,2,3}.txt\n\" "hello 1.txt " "hello 2.txt " "hello 3.txt
"
引数分割段階の後でパラメータ展開が行われているようです。
echo
は、2つの別々の引数helloと#.txtが渡され、単語の前に余分なスペースができます。
私はその診断に同意しません。 echo
は3つの引数(それぞれが\n
終わる)が渡され、 echo
は間にスペースを入れて忠実に出力します。 ここにバグはありません。
引数をデバッグするために私が行うことは次のとおりです。
~> printf '«%s»' hei\ {1,2,3}.txt\n
«hei 1.txt
»«hei 2.txt
»«hei 3.txt
»⏎
引数をデバッグするために私が行うことは次のとおりです。
私はstring escape
を使用します。
> string escape -- hello\ {1,2,3}.txt\n
hello\ 1.txt\n
hello\ 2.txt\n
hello\ 3.txt\n
つまり、あなたは実際に私が期待するものを手に入れるということです。 「1」、「2」、「3」の順に引数全体を取得します。 完全な引数には、たまたま改行が含まれています。
@mqudsi :ここであなたを
(command)
)のみを分割します。 つまり、ここでの\n
は、改行文字に置き換えられた後は特別な意味を持ちません。 残りの部分に関する限り、それは「キャラクター」です。 キャラクターを_エスケープ_する必要はありません。分割を実行しないだけです。または、 file (echo hello world.txt)
では、「helloworld.txt」はhello\ world.txt
にエスケープされません。改行がないため、分割されません。 hello\nworld.txt
というファイルがある場合、これにはbashのスペースの問題と同様の問題があります。
echo
は、引数の間にスペースを挿入します(「-s」が指定されていない場合)。 それが奇妙なインデントの原因です-スペースは改行の直後にあるからです。つまり、出力が必要な場合
hello 1.txt
hello 2.txt
hello 3.txt
echo -s
またはprintf '%s\n' hello\ {1,2,3}.txt
ます。
これはバグというよりは誤解だと思います。 私は正しいですか?
すみません、皆さん! 私は問題の最小限の再現を考え出そうとしていて、まったく異なる何かに混乱していました。 パラメータ展開の動作が間違っていました。特に、 parallel
またはxargs
の動作と混同しました。制限は1です。つまり、 echo {1,2,3}
は3に展開されると思いました。それぞれ1つの引数を持つコマンドであり、3つの引数を持つ1つのコマンドではありません。
私をまっすぐにしてくれてありがとう。