10

最初に少し背景を説明しapt-get installます。会社のインターネットからダウンロードすると、最初の 10 秒間は高速バースト (400 ~ 500KB/秒) になり、その後 10 分の 1 (40 ~ 50KB/秒) に落ちます。そして数分後、本当に惨めな状態になります (4-5KB/秒)。これは、システム管理者がある種のネットワーク スロットリング スキームを実装したと思わせます。

これで、ネットワークが単に不安定ではないことがわかりましapt-get install foo.すべてのパッケージがダウンロードされます。大きなパッケージでも非常に高速にダウンロードできます。特に、Ctrl-C でダウンロードを中断した後でも、apt-get は次の呼び出しでダウンロードを再開できるようです。Ctrl-Capt-get install foo

もちろん、10 秒ごとに Ctrl-C Up Enter を押しながら画面を見つめていると、すぐに飽きてしまうので、シェル スクリプトを作成しました。

#!/bin/sh
for i in `seq 1 100` ; do
    sudo apt-get install foo -y &
    sleep 10
    sudo kill -2 $!
done

これはうまくいくようです。apt-get を生成し、10 秒間実行してから (SIGINT を送信して) 強制終了し、再度起動します。ただし、apt-get はその後の呼び出しでダウンロードを再開しないため、実際には機能しません。

sudo apt-get install fooある端末から実行kill -2 <PID of apt-get>し、別の端末から実行した実験。その場合でも、apt-get を再起動しても、ダウンロードが再開されません。

したがって、明らかに Ctrl-C はSIGINT と同等ではありません。また、Ctrl-C を手動で実行すると、apt-get にダウンロードの状態を保存する機会が与えられます。問題は - それは何ですか?

編集

これらは私がこれまでに受け取った提案ですが、葉巻はありません. 謎が深まる!-

  1. 信号ではの代わりに にsudo kill -2 $!行く可能性があります。上記のように、特に apt-get の PID に SIGINT を送信しようとしても、apt-get がその状態を保存できないため、これは理由ではありません。sudoapt-get

  2. Sudo はシグナルをキャッチし、別のシグナルを apt-get に送信します。考えられるすべてのシグナルをapt-getに送信してみました!いずれのダウンロードも再開されません。Ctrl-C を実行して強制終了した場合にのみ、ダウンロードが再開されます。

  3. Apt-get は、対話型シェルではなくスクリプトからのものである場合、SIGINT を異なる方法で処理します。繰り返しますが、上記の「実験」は、これが正しくないことを証明しています。

4

3 に答える 3

5

よし謎解き!Indian Linux Users Groupの親切な人々に感謝します。

ここでの答えは2つあります -

まず、データをダウンロードするためにapt-get呼び出される別のプログラムを呼び出します。http

[~] ➔ file /usr/lib/apt/methods/http

/usr/lib/apt/methods/http: ELF 32-bit LSB executable, Intel 80386, version 1
(SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15,
stripped

これは実行可能ファイルであり、スクリプトでさえないことに注意してください。おそらく、perl/python/ruby などがまだ利用できない場合に、システムのインストール中にファイルのダウンロードをサポートするためのものです。

次に、 を実行した後に Ctrl-C を押すapt-getと、SIGINT はhttpではなく に送信されapt-getます。SIGINT を受信するhttpと、シャットダウンする前にダウンロード状態を保存します。

完全に機能する更新されたスクリプトは次のとおりです-

#!/bin/sh
for i in `seq 1 100` ; do
    sudo apt-get install foo -y &
    sleep 10
    sudo kill -2 `ps -ae | grep " http" | awk '{print $1}'`
done
于 2011-08-05T13:09:49.557 に答える
5

ヒント、単に SIGINT を送信するだけではありません)。

はい、単にSIGINT:-) を送信しているだけです。スロットリングが起こっているのです。これが私が起こっていると思われることです:

  • 何かが接続の帯域幅を制限しています。接続を追跡するために、他のパラメーターの中に送信元ポート (これは悪い考えです) も含まれています。

  • apt-get を強制終了して再起動すると、当然のことながら新しい TCP ソース ポートが取得され、スロットルを調整している邪悪なエンティティが「ああ、新しい接続だ」と考えるでしょう。

では、どのようにスピードアップしますか? 本当の解決策は、複数の並列ダウンロードを使用することです。私はそれを自分で使用したことはありませんが、このようなことを行う「apt-fast」(実際には bash スクリプト自体) というツールについて聞いたことがあります。

編集

質問をもう一度読んだ後、信号がに送信されていないapt-getと思われます。

sudo apt-get install foo -y &
sudo kill -2 $! # sends signal to sudo, which sends whatever it wants to `apt-get`

だから私はsudo信号をキャッチし、何か他のもの (sigterm? sighup?) を に送信すると信じていapt-getます。

于 2011-07-08T12:51:20.653 に答える
0

cnicutarが言ったように、SIGINT を送信しているだけです。さて、言われたことの鍵はここにあります:

シグナルが apt-get に送信されていないと思われます

これは本当です。説明させてください。

実行するとプロセスsudo fooが開始され、sudo次に(つまり、パスワードを挿入した後)呼び出されますfoo。論です。sudopasswd を受け入れて呼び出すと、の「スペースfoo」に入ります。完了するのを待っている間に何をしても、sudoではなく実行されます。foofoofoo

そのため、ジョブを実行するのCtrlCを待っている間に送信すると、そのシグナルは に送信されます。aptapt

ここで を起動するsudoと、そのpid$!がvarに格納されます。killその pid/var にシグナルを送信すると、後で sudo によって開始されたものではなく、にkillシグナルが送信されます。シグナルを送信したい場合は、おそらくユーティリティを使用したいと思うでしょう。sudoaptkillaptpidof

自分でテストしてください:

sudo do-something
echo $!
pidof do-something

出力は 2 つの異なるpidである必要があります。
それが少し役立つことを願っています。

于 2011-07-08T16:26:35.280 に答える