次のbashスクリプトがあります(この投稿に):
#!/bin/bash
while read LINE; do
curl -o /dev/null --silent --head --write-out "%{http_code} $LINE\n" "$LINE"
done < infile > outfile
入力ファイル:
google.com
facebook.com
結果ファイル:
301 amazon.com
302 facebook.com
質問:1行ずつ確認するのでとても遅いです。
テスト:私は次のような他の選択肢を試しました。平らな(リストのサイズを考慮すると非常に制限的です)素晴らしい(必ずぶら下げさせる)、得る、GNUパラレル待って、彼らの誰も私を説得できませんでした。そしてここxargsを使用するソリューションですが、出力は元のスクリプトとは異なります
質問:複数の行を同時に処理できるように、このスクリプトを使用して複数のクエリ(並列処理)を開始するにはどうすればよいですか?
修正する:解決しました! 。ありがとう
cat infile | xargs -I {} -P3 curl {} -o /dev/null --silent --head --write-out "%{http_code} {}\n" > outfile
PD:「-P 3」インスタンス番号
答え1
なぜならhttps://mywiki.wooledge.org/BashPitfalls#Non-atomic_writes_with_xargs_-P(並列ジョブの出力が混在する危険がありますxargs
。)代わりにGNU Parallelを使用します。
cat infile |
parallel -P0 -q curl {} -o /dev/null --silent --head --write-out "%{http_code} {}\n" > outfile
xargs
この特別な場合は、出力が短いため、使用しても安全です。したがって、これを使用する問題xargs
は、後で誰かがより大きなタスクを実行するためにコードを変更した場合、もはや安全ではないということです。あるいは、誰かがこの質問を読んでそれを別のものに置き換えることができると思うなら、curl
それも安全ではないかもしれません。
これはより速いかもしれません:
doit() {
while read LINE; do
curl -o /dev/null --silent --head --write-out "%{http_code} $LINE\n" "$LINE"
done
}
export -f doit
parallel -j0 --pipepart -a infile --block -10 doit > outfile
答え2
URLのリストを10個に分割し、デフォルトのスクリプトを使用できます。
./subscript1.sh &
./subscript2.sh &
...
./subscript10.sh &
並列に実行します。注:異なるログファイルを使用する必要があります。