GNUパラレル:空の文字列引数を使用してエクスポートされたbash関数を呼び出す方法は?

GNUパラレル:空の文字列引数を使用してエクスポートされたbash関数を呼び出す方法は?

想像する:

$ process(){ echo "[$1] [$2] [$3]" ; } ; export -f process

$ process "x" "" "a.txt"
[x] [] [a.txt]

ここでは、2番目のパラメータが空の文字列(予想)であることがわかります。

$ find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" ""
[x] [./a.txt] []
[x] [./b.txt] []
[x] [./c.txt] []

ここでは、2番目のパラメータが(予期せず)findの出力であることがわかります。

予想出力:

[x] [] [./a.txt]
[x] [] [./b.txt]
[x] [] [./c.txt]

どうすれば修正できますか?


""注:2番目の引数がからに変わると、"y"findの出力は3番目の引数(予想)として表示されます。

$ find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" "y"
[x] [y] [./a.txt]
[x] [y] [./b.txt]
[x] [y] [./c.txt]

なぜいいえfindの出力は、""?を使用して3番目の引数として使用されます。


UPD:解決策は次のとおりです\"\"

$ find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" \"\"
[x] [] [./a.txt]
[x] [] [./b.txt]
[x] [] [./c.txt]

しかし、これが正しい一般的な解決策であるかどうかはわかりません。以下は反例です。

$ VAR="" ; find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" "$VAR"
[x] [./a.txt] []
[x] [./b.txt] []
[x] [./c.txt] []

答え1

したがって、コマンドを直接実行するのではなく、シェルを介して並列に実行してください。まあ、そうしなければなりません。それ以外の場合、使用するシェル機能は機能しません。

これは、空白を持つパラメータが分割されることを意味します。

$ echo x | parallel process "foo bar" ""
[foo] [bar] [x]

個々の引数を引用してもコマンド全体を引用しても構いません。

$ echo x | parallel "process foo bar"
[foo] [bar] [x]

次のことができます。

$ echo x | parallel process '$(date +%F)'
[2024-02-29] [x] []
$ echo x | parallel "process foo bar > test.out"
$ cat test.out
[foo] [bar] [x]

任意の値を渡すには、シェルからその値を引用する必要があります。 Bashでは${var@Q}変数拡張を使用できます。

$ var="foo bar"; echo x | parallel process "${var@Q}"
[foo bar] [x] []

これを並列に実行するオプションがあるようです。

--quote -q 引用コマンド。コマンド; \ | *にシェルが解釈しないようにする特殊文字(例:)が含まれている場合は、--quoteこれらの文字をエスケープします。コマンドは、リダイレクトや変数の割り当てがない単純なコマンド(man bashを参照)でなければなりません。

「参照」セクションを参照してください。ほとんどの人はこれを必要としません。見積もりはデフォルトで無効になっています。

$ var="foo bar"; echo x | parallel --quote process "$var"
[foo bar] [x] []

もちろんこうすればリダイレクトなども中断されます。

$ var="foo bar"; echo x | parallel --quote process "$var" ">test.out"
[foo bar] [>test.out] [x]

もちろん、スペースを引用するので、コマンドパラメータを単一の文字列として渡そうとすると失敗します。


これを行うときに注意してください。

$ VAR="" ; ... parallel process "x" "$VAR"

変数には、引数として並列に渡される空の文字列のみが含まれます。と同じにするには、parallel process "x" \"\"変数に二重引用符(たとえば、VAR=\"\"またはVAR='""'対応する引用符)を使用する必要があります。または代わりに同様のものを使用してくださいparallel process "x" "'$VAR'"。変数自体にも引用符を含めることができる場合は、コンテンツを盲目的に引用符で囲むことができないことに注意してください。失敗します。

$ var="ain't so"; echo x | parallel process "'$var'"
/usr/bin/bash: -c: line 1: unexpected EOF while looking for matching `''
/usr/bin/bash: -c: line 2: syntax error: unexpected end of file

関連情報