221

xargs を使用して、より複雑な関数を並行して呼び出そうとしています。

#!/bin/bash
echo_var(){
    echo $1
    return 0
}
seq -f "n%04g" 1 100 |xargs -n 1 -P 10 -i echo_var {} 
exit 0

これはエラーを返します

xargs: echo_var: No such file or directory

xargs を使用してこれを達成する方法についてのアイデア、またはその他の解決策を歓迎します。

4

5 に答える 5

214

関数をエクスポートすると、それが実行されます(テストされていません):

export -f echo_var
seq -f "n%04g" 1 100 | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}

printfexternal の代わりにbuiltin を使用できますseq

printf "n%04g\n" {1..100} | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}

また、return 0and exit 0like that を使用すると、その前のコマンドによって生成される可能性のあるエラー値がマスクされます。また、エラーがない場合はデフォルトであり、多少冗長です。

@phobic は、Bash コマンドを次のように簡略化できると述べています。

bash -c 'echo_var "{}"'

{}その中に直接移動します。しかし、@Sasha が指摘したように、コマンド インジェクションに対して脆弱です。

埋め込み形式を使用してはならない理由の例を次に示します。

$ echo '$(date)' | xargs -I {} bash -c 'echo_var "{}"'
Sun Aug 18 11:56:45 CDT 2019

できない理由の別の例:

echo '\"; date\"' | xargs -I {} bash -c 'echo_var "{}"'

これは、安全な形式を使用して出力されるものです。

$ echo '$(date)' | xargs -I {} bash -c 'echo_var "$@"' _ {}
$(date)

これは、パラメータ化されたSQLクエリを使用してインジェクションを回避することに匹敵します。

非破壊的であるため、Sashaのコメントで使用されているコマンドのdate代わりに、コマンド置換またはエスケープされた引用符で使用しています。rm

于 2012-06-12T19:26:02.587 に答える
18

GNU Parallel を使用すると、次のようになります。

#!/bin/bash
echo_var(){
    echo $1
    return 0
}
export -f echo_var
seq -f "n%04g" 1 100 | parallel -P 10 echo_var {} 
exit 0

バージョン 20170822 を使用しているexport -f場合は、これを実行している限り必要ありません。

. `which env_parallel.bash`
seq -f "n%04g" 1 100 | env_parallel -P 10 echo_var {} 
于 2014-09-01T06:47:45.967 に答える
14

このようなものも動作するはずです:

function testing() { sleep $1 ; }
echo {1..10} | xargs -n 1 | xargs -I@ -P4 bash -c "$(declare -f testing) ; testing @ ; echo @ "
于 2016-06-22T11:56:25.947 に答える