web-dev-qa-db-ja.com

curlコマンドでのBashスクリプトのマルチスレッド化

これは、ドメインとそのパラメータを取得してステータスコードを検索するシェルスクリプトです。これは、スレッド化により高速に実行されますが、多くのリクエストが失われます。

while IFS= read -r url <&3; do
    while IFS= read -r uri <&4; do
    urlstatus=$(curl -o /dev/null --insecure --silent --head --write-out  '%{http_code}' "${url}""${uri}" --max-time 5 ) &&
    echo "$url  $urlstatus $uri" >> urlstatus.txt &
done 4<uri.txt 
done 3<url.txt

私が正常に実行した場合、すべてのリクエストが処理されますが、速度は非常に遅くなります。速度を維持し、すべてのリクエストを見逃さない方法があります。

5
user7423959

ファイルへの並列追加の問題が発生しています。簡単な答えは次のとおりです。しないでください。

GNU Parallelを使用してこれを行う方法は次のとおりです。

doit() {
    url="$1"
    uri="$2"
    urlstatus=$(curl -o /dev/null --insecure --silent --head --write-out  '%{http_code}' "${url}""${uri}" --max-time 5 ) &&
    echo "$url  $urlstatus $uri"
}
export -f doit

parallel -j200 doit :::: url uri >> urlstatus.txt

GNU Parallelはデフォルトで出力をシリアライズするため、あるジョブからの出力が別のジョブからの出力と混合されることはありません。

8
Ole Tange

複数のプロセスを非同期で実行できます( "shellcmd & "構文)シェルでは、サブプロセスは次のコマンドがその出力をキャプチャする前に終了する可能性があります(多くの場合、終了します)。そして、@ Ole-Tangeが指摘したように、その出力を正しい順序でファイルしてください!

多くの場合、シェルスクリプトを使用するのではなく、複数のスレッドを管理できる別のスクリプト言語を使用したいと考えています...

1
bb_referee