web-dev-qa-db-ja.com

wgetを強制的にタイムアウトさせる

X秒後にwgetを強制的に停止するにはどうすればよいですか?

画像をダウンロードするスクリプトがありますが、時々スタックして「タイムアウト」を拒否します。

私が試したこと:

--tries=3 --connect-timeout=30

ps auxから:

root     26543  0.0  0.0  38636  1656 ?        S    20:40   0:00 wget -nc --tries=3 --connect-timeout=30 --restrict-file-names=nocontrol -O 18112012/image.jpg http://site/image.jpg
5
teslasimus

Wgetコマンドをバックグラウンドプロセスとして実行し、SIGKILLを送信して、一定時間スリープした後に強制的に強制終了することができます。

_wget ... &
wget_pid=$!
counter=0
timeout=60
while [[ -n $(ps -e) | grep "$wget_pid") && "$counter" -lt "$timeout" ]]
do
    sleep 1
    counter=$(($counter+1))
done
if [[ -n $(ps -e) | grep "$wget_pid") ]]; then
    kill -s SIGKILL "$wget_pid"
fi
_

説明:

  • _wget ... &_-最後の_&_表記は、フォアグラウンドではなくバックグラウンドでコマンドを実行します
  • _wget_pid=$!_ --_$!_は、最後に実行されたコマンドのプロセスIDを含む特別なシェル変数です。ここでは、それを_wget_pid_という変数に保存します。
  • while [[ -n $(ps -e) | grep "$wget_pid") && "$counter" -lt "$timeout" ]]-1秒ごとにプロセスを探します。プロセスがまだ存在する場合は、タイムアウト制限まで待機し続けます。
  • _kill -s SIGKILL "$wget_pid"_-killを使用して、バックグラウンドで実行されているwgetプロセスを SIGKILLシグナル を送信して強制的に強制終了します。
2
sampson-chen

最も簡単な方法は、GNU coreutilsの一部であるtimeout(1)コマンドを使用することです。したがって、bashがインストールされているほとんどの場所で利用できます。

timeout 60 wget ..various wget args..

または、実行時間が長すぎる場合にwgetをハードキルしたい場合:

timeout -s KILL 60 wget ..various wget args..
12
Chris Dodd

最近、wget 1.14がサイレントに-timeoutオプションを無視していることに気付きました。これを1.19に更新すると問題なく動作しました。

0
adrianTNT

これは主にsampson-chenの回答のコピーであるため、コミュニティwikiですが、いくつか指摘したいと思います。

wget ... &
# Strictly speaking you can just use the job number,
# which is probably %1, but saving the pid is also fine.
wget_pid=$! 
counter=0
timeout=60
# use kill -0 to check if a pid is still running
while kill -0 "$wget_pid" && (( counter < timeout )); do
    sleep 1
    (( counter++ ))
done
# if killing nothing is distasteful, use kill -0 one more time.
# also think a SIGKILL is overkill since the question doesn't imply wget needs it.
kill -0 "$wget_pid" && kill "$wget_pid"
0
kojiro