Curl コマンドの Bash スクリプトのマルチスレッド

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

正常に実行するとすべての要求を処理しますが、非常に遅くなります。スピードを維持しながらすべてのリクエストを見逃さない方法はありますか?

答え1

ファイルを並列に追加する際に問題があります。簡単な答えは:しないでください。

GNUパラレルを使用する方法は次のとおりです。

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 はデフォルトで出力をシリアライズするため、あるジョブの出力が別のジョブの出力と混在することはありません。

GNU Parallelを使用すると、入力を出力に簡単に含めることができます--tag。したがって、出力形式が固定されていない場合は、次のようにします。

parallel --tag -j200 curl -o /dev/null --insecure --silent --head --write-out  '%{http_code}' {1}{2} --max-time 5 :::: url uri >> urlstatus.txt

異なる形式で同じ出力を提供します。変える:

url  urlstatus uri

あなたは以下を得ます:

url uri urlstatus

答え2

複数実行できますが、プロセスシェルでは、非同期的に(" shellcmd &"構文を使用する)サブプロセスは、次のコマンドが出力をキャプチャする前に終了することがあり、しばしば終了します。そして@Ole-Tangeが指摘したように、この出力が正しい順序でファイルに書き込まれることを確認する方法はありません!

多くの人がシェルスクリプトを使用するのではなく、複数のスレッドを管理するために異なるスクリプト言語を使用したいと考えています。

答え3

複数のカール転送を並列に実行するには、xargsという別のツールを検討する必要があります。

xargsに慣れていない場合、これは非常に強力なLinuxユーティリティです。これにより、いくつかのオーバーヘッドで複数の(動的)カールコマンドを並列に実行できます。例:

seq 1 3 | xargs -n1 -P3 bash -c 'i=$0; url="http://mytestserver.net/10m_test.html?run=${i}"; curl -O -s $url'

このコードは3つのカールコマンドを並列に実行します。 -Pパラメーターを使用すると、希望の並列実行数を設定できます。この例では、seqコマンドを使用して、各URLが一意の実行番号を持つようにコマンドに数値引数を渡します。 -nパラメーターは、単に実行ごとに渡されるパラメーターの数を制限します。 -cパラメーターは、実行するコマンドを指定する場所です。

この例では、出力を提供せずに転送のみを実行することに注意してください。出力を保存する場合は、出力形式の前の説明を使用して、出力する内容と保存方法を決定できます。

ここでは、繰り返し回数を増やして他の興味深いパラメータ(ファイルのURLリストなど)を渡すことができます。バックグラウンドトラフィックを生成するときに特定のネットワーク条件をシミュレートするためにこれらのコマンドを頻繁に使用します。

関連情報