あなたがプログラムを内部的に開始されている方法とどのようにコマンドがシェルによって解釈されますについて混乱しているようだ。
でunix、プログラムを開始するには3つのパラメタrs:
- ファイル名。これは、実行するプログラムへのパスを含む文字列です。
- 文字列のリスト。規約では、これらの「コマンドライン引数」を呼び出します。
- 文字列の別のリスト。大会ではこれらを「環境」と呼んでいますが、OSレベルではもう一つの文字列リストです。しかし、すべてのプログラム/ライブラリは、これをユーザとアプリケーションプログラマの両方に隠すために共謀しています。
あなたがシェルにコマンドを入力すると、多くのことが起こるが、最も簡単な場合には、それはスペースで区切られた単語のちょうど束だ:
$ foo bar baz
($
は、シェルプロンプトではなく、何かを表し、あなたが入力します。)シェルは3つのワード(foo
、bar
、baz
)にこの行を分割し、プログラムの名前として最初のものを解釈
(PATH
Vに記載されているディレクトリで検索しますariable)。 PATH
リストを/usr/bin
とし、実際には/usr/bin/foo
プログラムがあるとしましょう。
今シェルは次のようにプログラムを開始する(擬似コード):
exec("/usr/bin/foo", ["foo", "bar", "baz"], [...])
すなわち/usr/bin/foo
で実行可能ファイルを実行し、引数として3つの文字列のリストを渡します。 ([...]
はこれから無視する環境を表しています。)
代わりにこれを行うとどうなりますか?
$ foo "bar baz"
引用符は、シェルが行を単語に分割する方法に影響します。特に、引用符で囲まれた" "
(スペース)は区切り文字としては機能しませんが、文字通り取られます。これにより、2要素のリスト(foo
、bar baz
)が得られます。引用符は単語そのものではないことに注意してください。
内部的にはこれは、次の呼び出しに変換します。
exec("/usr/bin/foo", ["foo", "bar baz"], [...])
は再び、第二引数は、単純にスペースが含まれています。埋め込み引用符はありません。
だから何が
$ xargs -pi find ~/Multimedia/Musik/flac/ -name "\""{}"\""
のようなコマンドでどうなりますか?
これは、シェルによって単語のリストに解析されます。 ~
は、ホームディレクトリの名前に置き換えられます。 "\""
は、\"
または'"'
(すなわち、リテラル"
文字)を書く複雑な方法です。最終的なリストはxargs
,-pi
,find
,/home/madZeo/Multimedia/Musik/flac/
,-name
,"{}"
です。最後の引数は4文字の文字列"{}"
がいかに
exec("/usr/bin/xargs", ["xargs", "-pi", "find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "\"{}\""], [...])
注:これは、次の呼び出しに変換します。
xargs
は、その最初の引数(-pi
)をオプション指定として扱います。特に、-i
は、引数リスト内の{}
を標準入力から読み取られた現在の値で置き換えるよう指示します。
xargs
標準入力から(echo
パイプのため)01.Here Comes The Night Time II.flac
という行が読み込まれます。
これは、リストfind
、/home/madZeo/Multimedia/Musik/flac/
、-name
、"01.Here Comes The Night Time II.flac"
を得{}
の代わりに中に置換されます。 xargs
は、このようなfind
を起動します:
exec("/usr/bin/find", ["find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "\"01.Here Comes The Night Time II.flac\""], [...])
これは、名前が文字通り"
(引用符)で始まるファイルを検索するfind
に指示します。そのようなファイルは存在しないので、これは失敗します。
修正は、このようなコマンドを書くことである:
$ xargs -pi find ~/Multimedia/Musik/flac/ -name {}
これは最終的に何をしたいである、
exec("/usr/bin/find", ["find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "01.Here Comes The Night Time II.flac"], [...])
を実行して終了します。
xargs
は、サブコマンド(この場合はfind
)を直接実行するという問題があります。シェルによって再解析される新しいコマンドラインは構築されません。それは入力引数をスペースで分割しません。引用符は解釈しません。$
または*
または\
のような特殊文字は気にしません。与えられた単語のリストを取り、サブ文字列{}
を現行の入力で置き換えて実行します。
この最終コマンドを慎重に受け取り、シェルに貼り付けると、言葉の分割、引用の削除などが行われ、異なる結果につながります。
'... -name {}'はどうなりますか? – melpomene
"xargs -pi find〜/ Multimedia/Musik/flac/-name {}"(-0オプションなし)コマンドを実行すると、これは私が試していない唯一の組み合わせであったようです。しかし、なぜ今働いていますか?これによりxargsのコマンド要求が出てきます。 "find〜/ Multimedia/Musik/flac/-name 01.Here Comes The Night Time II.flac"となり、この "コピー&ペースト"は機能しません。 – madZeo
重い手紙の編集を許しますが、これは同じ質問を他の人に向けた最初のアプローチです(また、質問されている内容に正確に答えることに興味がある人には明らかになります)。 –