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を使用してこれを達成する方法、またはその他の解決策に関するアイデアは歓迎します。
関数をエクスポートすることで実行できます(未テスト):
export -f echo_var
seq -f "n%04g" 1 100 | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}
外部printf
の代わりに組み込みseq
を使用できます。
printf "n%04g\n" {1..100} | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}
また、そのようなreturn 0
およびexit 0
を使用すると、その前のコマンドによって生成される可能性のあるエラー値がマスクされます。また、エラーがない場合はデフォルトであるため、多少冗長です。
@phobicは、Bashコマンドcouldは
bash -c 'echo_var "{}"'
{}
をその中に直接移動します。 しかしそれはコマンドインジェクションに対して脆弱 @Sashaが指摘したとおりです。
使用しない埋め込み形式の理由の例を次に示します。
$ echo '$(date)' | xargs -I {} bash -c 'echo_var "{}"'
Sun Aug 18 11:56:45 CDT 2019
why notの別の例:
echo '\"; date\"' | xargs -I {} bash -c 'echo_var "{}"'
これが出力です安全な形式を使用:
$ echo '$(date)' | xargs -I {} bash -c 'echo_var "$@"' _ {}
$(date)
これは、 パラメータ化 SQL クエリ を使用して インジェクション を回避することに匹敵します。
ここでは、非破壊的であるため、Sashaのコメントで使用されているdate
コマンドの代わりに、コマンド置換またはエスケープされた引用符でrm
を使用しています。
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 {}
このようなものも動作するはずです:
function testing() { sleep $1 ; }
echo {1..10} | xargs -n 1 | xargs -I@ -P4 bash -c "$(declare -f testing) ; testing @ ; echo @ "
たぶんこれは悪い習慣ですが、.bashrc
または他のスクリプトで関数を定義している場合は、allexport
の設定でファイルまたは少なくとも関数定義をラップできます。
set -o allexport
function funcy_town {
echo 'this is a function'
}
function func_rock {
echo 'this is a function, but different'
}
function cyber_func {
echo 'this function does important things'
}
function the_man_from_funcle {
echo 'not gonna lie'
}
function funcle_wiggly {
echo 'at this point I\'m doing it for the funny names'
}
function extreme_function {
echo 'goodbye'
}
set +o allexport