私はURLファイルを読み込み、各URLのHTTPステータスコードを出力するDebianシステムにスクリプトを書いています。
...
while read url
do
urlstatus=$(curl -H 'Cache-Control: no-cache' -o /dev/null --silent --head --insecure --write-out '%{http_code} ; %{redirect_url}' "$url")
...
done < $1
100個のURLを含むファイルには問題はありませんが、1000個を超えるURLを含む大きなファイルの場合、スクリプトは非常に遅くなります!
SOで見つけたいくつかの「ヒント」を試しました。 KeepAlive設定-H 'Keep-Alive: 500'
、GoogleBotをユーザーエージェントとして定義、--user-agent 'Googlebot/2.1 (+http://www.google.com/bot.html)'
接続タイムアウト定義などが--connect-timeout 1
ありましたが、何もありません!
ベストアンサー1
並列に実行するには、GNU Parallelを使用できます。
#!/usr/bin/env bash
file=$1
status_func () {
local _url="${1:-/dev/stdin}"
local _urlstatus
_urlstatus=$(curl -H 'Cache-Control: no-cache' -o /dev/null --silent --head --insecure --write-out '%{http_code} ; %{redirect_url}' "$_url")
printf 'Status: %s\n' "$_urlstatus"
}
export -f status_func
cat "$file" | parallel -j20 status_func
-j オプションは、最大同時ジョブ数を設定します。デフォルトはシステムのスレッド数ですが、最良の結果を得るにはこの数を調整する必要があります。
コマンドを関数(またはまったく別のスクリプト)に追加し、並列処理がそれを知るために関数をエクスポートする必要があることに注意してください。
コマンドをスタンドアロンスクリプトに配置するには、次のようにコマンドラインから実行できます。
cat "$file" | parallel -j20 ./my_script.sh
このスクリプトはstdinを介して送信されたURLのみを期待する必要があります。
また、GNU 並列処理を使用できない場合でも、複数のジョブを同時に実行したい場合は、そのジョブをバックグラウンドジョブとして実行できますが、同時プロセス数を制限したい可能性があります。これは次の方法で行うことができます。
#!/usr/bin/env bash
file=$1
max_bg_procs () {
local max_number=$((0 + ${1:-0}))
while :; do
local current_number=$(jobs -pr | wc -l)
if [[ $current_number -lt $max_number ]]; then
break
fi
sleep 2
done
}
status_func () {
local _url="${1:-/dev/stdin}"
local _urlstatus
_urlstatus=$(curl -H 'Cache-Control: no-cache' -o /dev/null --silent --head --insecure --write-out '%{http_code} ; %{redirect_url}' "$_url")
printf 'Status: %s\n' "$_urlstatus"
}
while IFS= read -rd url; do
max_bg_procs 20
status_func "$url" &
done < "$file"