Bash:コマンド置換の引用

Bash:コマンド置換の引用

つまり、次のコマンドでリストされたディレクトリを使用したいと思いますfind

find $(produces_dir_names --options...) -find-options...

問題は、ディレクトリ名にスペースがあることです。ビルドコマンドの出力でこれを引用すること(変更可能)であれば十分だと思います。

"a" "a b" "a b c"

しかし、bashは次のように文句を言います。

find: ‘"a"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b’: No such file or directory
find: ‘c"’: No such file or directory

ご覧のとおり、bash引用符を使用している場合でも空白にコマンド出力を分割します。私はこれに触れてIFS設定してみました\nが、うまくいくには私の理解が限られているようです。

私が見つけた唯一の解決策は、このスタックオーバーフローの質問にあります。 bash コマンドの置換引用符の削除つまり、eval前に一つを置くのがちょっと見苦しく見えます。

私の質問:

簡単な方法はありますか?なしでこの代替品を作成するのはどのようなものでしょうかeval

見積もりはまだ必要ですか?

はい(同じ出力を生成):

find $(echo '"a" "a b" "a b c"')

答え1

おそらく2行

IFS=$'\n' DIRS=( $(produces_dir_names --options...) ) 
find "${DIRS[@]}" -find-options...

例:

$ mkdir -p "/tmp/test/a b/foo" "/tmp/test/x y/bar"

$ IFS=$'\n' DIRS=( $(printf "/tmp/test/a b\n/tmp/test/x y\n") )
$ find "${DIRS[@]}" -mindepth 1
/tmp/test/a b/foo
/tmp/test/x y/bar

しかし、全体的に良いスタイルではありません。たとえば、DIRS に改行文字が含まれている場合、問題が発生します。ヌルバイトで終わる文字列を印刷するには、「Produces_dir_names」を変更することをお勧めします。私の例は次のとおりです。

$ printf "/tmp/test/a b\0/tmp/test/x y\0" | xargs -0 -I '{}' find '{}' -mindepth 1
/tmp/test/a b/foo
/tmp/test/x y/bar

私の最後のコメントに関して "products_dir_names"を変更できない場合、最も一般的な解決策は次のとおりです。

produces_dir_names --options... | tr '\n' '\0' | xargs -0  -I '{}' find '{}' -find-options...

「newlines」を避けるために「Produces_dir_names」を変更しない限り、「newlines」にはまだ問題がありますtr

答え2

ルディ・マイヤーの答え大丈夫です。特に、nullで終わる文字列を印刷するように変更する部分です。しかし、彼の答えでは、各ディレクトリに対して一度だけ実行するproduces_dir_names ことは明らかではありません。findそれくらいなら大丈夫です。しかし、もちろん、find 次のような複数の始点を使用して呼び出すことも可能です。

探す  ディレクトリ1ディレクトリ2ディレクトリ3  -オプションを探す...

質問では、これがあなたが望むようです。これは次のように実行できます。

printf "a\0a b\0a b c" | printf "a\0a b\0a b c" | xargs -0 sh -c '"$@"を探す -オプションを探す...'多様

これにより、すべてのディレクトリ名がコマンドに追加された単一のxargs呼び出しが発生します。sh -cその後、シェルは"$@"これらのディレクトリ名のリストを展開します。

PS produces_dir_names1 つのコマンドラインに入れることができないほどディレクトリ名があまりにもリストされている場合は、xargsいくつかのコマンドを生成する必要があります。どのコマンドが生成されるかをxargs --verbose確認するために使用されます。xargs

答え3

表示されるエラーメッセージを理解するには、次の手順を実行します。

find: ‘"a"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b"’: No such file or directory
find: ‘"a’: No such file or directory
find: ‘b’: No such file or directory
find: ‘c"’: No such file or directory

正解はBash 引用符の削除は、次の引用符を削除しません。結果コマンドの置き換えから。

~からLESS='+/^ *Quote Removal' man bash

Quote Removal
    After the preceding expansions, all unquoted occurrences of the charac-
    ters  \,  ', and " that did not result from one of the above expansions
    are removed.

「上記の拡張」への参照は次のとおりです。

EXPANSION
   Brace Expansion
   Tilde Expansion
   Parameter Expansion
   Command Substitution
   Arithmetic Expansion
   Process Substitution
   Word Splitting
   Pathname Expansion
   Quote Removal

関連情報