[解決済み] Bashでwgetを並列化する [重複].
質問
私はウェブサイトから比較的小さなページの束を取得しており、どうにかしてBashで並行してそれを行うことができないかと考えていました。現在、私のコードは次のようになりますが、実行に時間がかかります (私を遅くしているのは、接続の待ち時間だと思います)。
for i in {1..42}
do
wget "https://www.example.com/page$i.html"
done
xargsを使用することを聞いたことがありますが、私はそれについて何も知らないし、マニュアルページは非常にわかりにくいです。 何かアイデアはありますか?これを並列で行うことは可能でしょうか?これを攻撃するために行くことができる他の方法はありますか?
どのように解決するのですか?
を押すことが望ましいです。
wget
を背景に押し出す方がはるかに好ましいです。
&
または
-b
を使用することができます。
xargs
を使うと、同じ効果、より良い効果が得られます。
利点は
xargs
は
正しく同期する
を追加作業なしで実行します。これは、ダウンロードしたファイルに安全にアクセスできることを意味します(エラーが発生しないことを前提としています)。すべてのダウンロードが完了(または失敗)した時点で
xargs
が終了すると、すべてのダウンロードが完了(または失敗)し、 すべてがうまくいったかどうかを終了コードで知ることができます。この方法は
sleep
で忙しく待ち、手動で完了をテストするよりもずっと好ましいことです。
と仮定して
URL_LIST
がすべての URL を含む変数であると仮定して(OP の例ではループで構築できますが、手動で生成したリストでもかまいません)、これを実行します。
echo $URL_LIST | xargs -n 1 -P 8 wget -q
は一度に一つの引数を渡します (
-n 1
) を
wget
を実行し、最大8つの並列
wget
プロセスを同時に実行します (
-P 8
).
xarg
は最後に生成されたプロセスが終了した後に返されます。 これはまさに私たちが知りたかったことです。余分なトリックは必要ありません。
私が選択した 8 並列ダウンロードというマジック ナンバーは明確なものではありませんが、おそらく良い妥協点だと思います。一連のダウンロードを最大化するには、2 つの要素があります。
1 つは、ケーブルを埋めること、つまり、利用可能な帯域幅を利用することです。通常の条件 (サーバーの帯域幅がクライアントより大きい) を仮定すると、1 つまたはせいぜい 2 つのダウンロードですでにこのような状態になっています。この問題にさらに接続を投入すると、パケットがドロップされ、TCP 輻輳制御が作動するだけであり、また N のダウンロードで、漸近的に 1/N の各帯域幅で、同じ正味の効果 (ドロップされたパケットを差し引き、ウィンドウ サイズの回復を差し引く) を得ることができます。パケットを廃棄することは IP ネットワークで起こる普通のことで、輻輳制御は (単一接続であっても) このように機能することになっており、通常、その影響は実質的にゼロです。しかし、不当に多くの接続があると、この影響が増幅されるため、目立ってくることがあります。いずれにせよ、これによって何かが速くなるわけではありません。
2つ目の要因は、接続の確立とリクエストの処理です。ここで、飛行中の余分な接続をいくつか持つことは
は本当に役に立ちます。
. 問題は、2往復の遅延 (通常、同じ地域内では 20-40ms 、大陸間では 200-300ms) と、サーバーが実際にリクエストを処理し、ソケットに応答を送るのに必要な奇妙な 1-2 ミリ秒の遅延です。これは大した時間ではありません。
それ自体
しかし、数百/数千のリクエストに乗算されると、それはすぐに積み重なります。
飛行中に半ダースから1ダースのリクエストがあると、この遅延のほとんどまたはすべてが隠れます(まだありますが、重なっているので、合計されません!)。同時に、わずか数回の同時接続は、過度の輻輳を引き起こしたり、サーバーに新しいプロセスをフォークさせたりするような悪影響を与えません。
関連
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bashで文字列が部分文字列を含むかどうかをチェックする方法
-
[解決済み] Bash prints リテラルの改行をエコーする \n
-
[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み] Bashでコマンドライン引数を解析するには?
-
[解決済み】Bashでファイル名と拡張子を抽出する。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 現在の日付と時刻を句読点を使わずに表示する
-
[解決済み] bashで変数に改行を埋め込もうとする [重複].
-
[解決済み] Bashで引用符で囲まれた文字列の中で環境変数を使用する方法
-
[解決済み] シェルスクリプトで文字列が空でもスペースでもないことをチェックする
-
[解決済み] bashでWebサーバーの応答を待つループを作成するには?
-
[解決済み] bash スクリプトで ENTER キー押下をシミュレートする
-
[解決済み] Bashでforループを書くには?
-
[解決済み] 引用符で囲まれたパラメータを受け取り、再送するためのBashスクリプト
-
[解決済み] ファイル名の一部をリネームする [重複]。
-
[解決済み] Bashで文字列の一文字目を削除する