wgetの可能性を広げる

こんにちは。



それで、私はHabrの本格的なユーザーになりました。 この記事に招待してくれた人に感謝したい:


少し前まで、Linux(特にUbuntu 8.10)での作業を理解し始め、リストからファイルを自動的にダウンロードするタスクがありました。 「Wget -i」は確かに良いことですが、私はもっと欲しかった、つまり:

  1. ファイルからリンクのリストをダウンロードする
  2. 一度に複数のファイルをダウンロードする
  3. 失敗したダウンロードを別のリストに転送して、再試行します。


そのため、wgetが提供できるよりもわずかに高度なファイルのダウンロードツールが必要でした。 bashを使用して実装することにしました。 真実はbashスクリプトを書く経験の不足を妨げるかもしれませんが、ちょうど週末に来ました、そして、トピックに関する材料に費やされた時間は無駄ではありませんでした。



私の仕事の結果は次のスクリプトでした:



更新: ヒントのおかげで、zencdwaitコマンドを使用してダウンロードが完了するのを待ちました。

更新2: shulcはエラーを指摘しました: #!/ Binbash#!/ Bin / shに置き換えました。 darkkは、一時ファイルを作成するためのmktempの存在を提案しました。

#!/bin/sh

log_dir= "${PWD}/log"

list_dir= "${PWD}/list"

output_dir=${PWD}

# download_list -

download_list= "${list_dir}/download.lst"

# active_list

active_list= "${list_dir}/active.lst"

# done_list

done_list= "${list_dir}/done.lst"

# error_list

error_list= "${list_dir}/error.lst"

# $timeout -

timeout=5



# $1 $2 $3,

# move_line line source_file dest_file

move_line()

{

tmp_file=`mktemp -t downloader.XX`

echo $1 >> $3

cat $2 | grep -v $1 > $tmp_file

mv $tmp_file $2

}



# , $1

download_thread()

{

thread=$1

# , download.lst error.lst

while [ -s $download_list ] || [ -s $error_list ]

do

# download.lst - error.lst

if [ ! -s $download_list ]

then

read url < $error_list

move_line $url $error_list $download_list

sleep $timeout

fi

read url < $download_list

move_line $url $download_list $active_list

echo "[Thread ${thread}]Starting download: $url"

#

wget -c -o "${log_dir}/wget_thread${thread}.log" -O "${output_dir}/$(basename " $url ")" $url

# wget ( 0 - )

if [ $? -eq 0 ]

then

#

move_line $url $active_list $done_list

echo "[Thread ${thread}]Download successful: $url"

else

# -

move_line $url $active_list $error_list

echo "[Thread ${thread}]Error download: $url"

fi

done

return 0

}



# active.lst

stop_script()

{

#

kill -9 `ps ax | grep $0 | grep -v "grep" | awk '{print $1}' | grep -v $$`

# active.lst

while [ -s $active_list ]

do

read url < $active_list

move_line $url $active_list $download_list

kill -9 `ps ax | grep $url | grep -v "grep" | awk '{print $1}' `

done

}



case "$1" in

"stop" )

echo "Stoping downloader..."

stop_script

echo "Done..."

;;

"start" )

#

if [ ! -e $download_list ];

then

echo "[Error] There is no ${list_dir}/download.lst file"

exit

fi

echo "Starting downloader..."

#

stop_script

# - $2, 1

if [ -z $2 ]

then

threads=1

else

threads=$2

fi

#

i=1

while [ $i -le $threads ]

do

download_thread $i &

downloader_pid= "${downloader_pid} $!"

sleep 1

i=`expr $i + 1`

done

if [ ! -e $error_list ]; then touch $error_list; fi

#

wait $downloader_pid

# ...

echo "All completed"

;;

* )

echo "Usage:"

echo "\t$0 start [number of threads]"

echo "\t$0 stop"

;;

esac



return 0




* This source code was highlighted with Source Code Highlighter .






スクリプトを機能させるには、スクリプトを実行可能にし、ダウンロードリンクのリストを含むファイル "./list/download.lst"を作成する必要があります。



打ち上げ:

sh downloader start [ ]





または、 Mezomishが正しく指摘したように、次のように:

./downloader start [ ]







'start'の後のパラメーターはオプションです(指定しない場合は、「1」が使用されます)。

つまり `sh downloader start 2`は同時に2つのファイルをダウンロードしながらスクリプトを実行します。



停止:

sh downloader stop





または

./downloader stop







スクリプトが「Ctrl + C」で終了しても、ダウンロードは終了しません。 バックグラウンドで動作するため、上記のコマンドを実行してダウンロードを停止する必要があります。



スクリプトを散らかさないことにしましたが、原則として、リストを操作するのは難しくありません(表示-表示、追加-ダウンロードの追加、ワイプ-クリア)。 そのため、最小限の機能を備えていますが、彼は労働者です。



なぜなら これが私の最初のbashスクリプトです。コメント/提案/推奨事項は大歓迎です。



さらに、スクリプトの原則について簡単に説明します。これにより、ニーズに合わせてスクリプトを変更する方が簡単になります。



定数は以下を示します。

log_dir-wget'aログのあるフォルダー(デフォルトでは「./log」)

list_dir-リストdownload_list、active_list、done_list、error_list(デフォルトは "./list")

output_dir-ダウンロードされたファイルが保存されるフォルダー(デフォルトでは「。」)

download_listダウンロードリンクのリスト

active_list-アクティブなダウンロードのリスト

done_list-完了したダウンロードのリスト

error_list-失敗したダウンロードのリスト

タイムアウト-ダウンロードの再試行に失敗するまでの時間



作業の開始時に、スクリプトは以前に起動したコピーを停止し、active_list(もしあれば)からのダウンロードをdownload_listに転送して停止します。 これは、以前に起動したプロセスによってダウンロードが完了する前にスクリプトが再起動された場合に実行されます。 さらにループでは、必要な数のバックグラウンドダウンロードが作成されます。 このような各バックグラウンドスレッドは、download_thread()関数によって実装されます。 その仕事は、download_listとerror_listが空になるまでリストからファイルをダウンロードすることです。 したがって、これらのファイルをチェックするスクリプトの主要部分は、ダウンロードが終了したかどうかを調べます。 wgetを開始する前に、リンクはdownload_listファイルからactive_listファイルに転送されます。 wgetが完了すると、リンクはdone_list(戻りコードが「0」の場合)またはerror_list(戻りコードが「0」に等しくない場合)に転送されます。

すべてがダウンロードされた後(download_listとerror_listは空です)、スクリプトは作業を終了します。



以上です。 必要に応じて、スクリプトに少し精通している人なら誰でも必要な機能を追加できます。



All Articles