
以下を実行するbashスクリプトが必要です。
- wgetを使用して3つのファイルを同時にダウンロードすると、同時に完了する必要はありません。
- 同時に3つのダウンロードをキャンセルできます
CTRL+C
(完了したダウンロードを除く)。
現在、私はwget -c URL
各端末で3つの並列インスタンスを実行しています。ただし、Linuxの再起動後に続行できるように、ユーザー入力がキャンセルされるのを待つスクリプトが必要です。
私のシステムはCygwinがインストールされているWindowsです。
答え1
parallel
これを達成するためにGNUを使用できます。 URLを配列に入れて、次wget
を実行しますparallel
。
#!/bin/bash
urls=( "https://example.com" "https://example1.com" "https://example2.com")
parallel wget -c ::: "${urls[@]}"
Parallelはコマンドを並列に実行し、スクリプトを停止します(たとえば、Ctrl+を使用するとC並列処理が終了し、完了したインスタンスに影響を与えずに実行中の3つのwgetインスタンスがすべて終了します。
parallel
オペレーティングシステムリポジトリに見つかる必要があります。
インストールしたくない場合やインストールできない場合は、parallel
bashからローカルにインストールすることもできます。
#!/bin/bash
trap 'kill $(jobs -p)' EXIT
urls=( "https://example.com" "https://example1.com" "https://example2.com" )
for url in "${urls[@]}"; do
wget -c "$url" &
done
wait
ここでの秘密は、trap
組み込み関数(help trap
bashを参照)を使用して次のことを行います。罠kill $(jobs -p)
EXIT信号コマンド。jobs -p
現在のシェルのすべての子プロセスのPIDが返されるため、この場合は実行中のwget
プロセスのPIDになります。これらはkill
殺された場所に渡されます。したがって、スクリプトを終了するとサブスクリプトに渡されます。 +killスクリプトを使用してプロセスを終了wait
できるように終了する前に、すべてのバックグラウンドジョブの実行が完了するまでスクリプトが待機していることを確認してください。wget
CtrlC
答え2
Bashスクリプトは次の場所にあります。この他の答えBashは別のプロセスグループでコマンド(非同期コマンドを含む)を実行するため、トラップが必要です。端末はフォアグラウンドプロセスグループについて知っており、Ctrlそのグループに+のSIGINTを送信しますc。 Bashスクリプトがwait
フォアグラウンドにある場合、それbash
自体はフォアグラウンドプロセスグループに属しますが、wget
自分が作成したプロセスグループには属しません。 SIGINT(存在する場合)はsのbash
代わりに到着しますwget
。そのため、上記の回答にトラップが必要です。
他のシェルは異なる動作をする可能性があります。私のKubuntuでは、posh
新しいプロセスグループは作成されず、自分が属するプロセスグループのすべてを実行します。これにより、スクリプトを簡素化できます。
#!/usr/bin/posh
set -- 'https://example.com' 'https://example1.com' 'https://example2.com'
for url do
wget -c "$url" &
done
wait
スクリプトがフォアグラウンドで実行中に+を押すと、Ctrl端末はSIGINTを直接送信します。cposh
そしてwget
フォアグラウンドプロセスグループと同じプロセスグループにあるためです。
メモ:
posh
配列はサポートされていないため、URLを位置パラメータとして保存します。そのset …
行を削除してからスクリプトを呼び出すときにURL(たとえば)を指定できます./the_script 'https://example.com' 'https://example1.com' 'https://example2.com'
。これにより、スクリプトをランダムなコンテンツを並列にダウンロードするためのツールに置き換えることができます。- トラップに使用される別の答えは、
kill
基本信号がSIGTERMであり、これはSIGINTと同じではありません(wget
同じ方法で反応することができます)。kill
SIGINTまたは他の信号を送信することができ、オプションです(kill -s …
)。私たちのスクリプトでは選択肢はありません。我々は信号を伝達せず、信号を生成しません。Ctrlまずc、端末でSIGINTをスクリプトを解釈するシェルだけでなくsにも送信するようにすべてを設定しましたwget
。
他の答えは良いです。 GNUがparallel
正しいツールであり、Bashがtrap
機能する必要があるため、ある意味では私の答えは必要ありません。私はまだCtrl+がどのようにc機能するのか、そしてさまざまなシェルがどのように機能するのかを知っていれば、あなたが望む動作を得るために別のシェルを選択できることを示したいと思います。