bash - 当您执行 Ctrl-C 时 BASH 中会发生什么(提示,它不仅仅是发送 SIGINT)

标签 bash process kill apt sigint

先介绍一下背景 - 当我做的时候 apt-get install从我公司的互联网下载它在前 10 秒左右提供高速爆发 (400-500KB/s),然后下降到十分之一 (40-50KB/s),然后几分钟后真惨(4-5KB/s)。这让我觉得系统管理员实现了某种网络节流方案。

现在我知道网络不仅仅是不稳定的,因为如果我启动 apt-get install foo , Ctrl-C 10 秒后立即运行 apt-get install foo再次(按向上箭头并输入以使用 bash 历史记录),然后重复这个过程几分钟直到所有包都下载完毕,我可以非常快地下载大包。特别是,即使在使用 Ctrl-C 中止下载后,apt-get 似乎也能够在下一次调用时恢复下载。

当然,每 10 秒盯着屏幕执行 Ctrl-C Up Enter 很快就会变得非常无聊,所以我写了一个 shell 脚本 -

#!/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 $!信号可能会转到 sudo而不是 apt-get .这不是原因,因为如上所述,我还尝试将 SIGINT 专门发送到 apt-get 的 PID,甚至阻止 apt-get 保存其状态。

  2. Sudo 捕获信号并将一些其他信号发送到 apt-get。我尝试发送 apt-get 我能想到的所有信号!它仍然不会恢复其中任何一个的下载。它只会在我按 Ctrl-C 将其终止时恢复下载。

  3. 如果 SIGINT 来自脚本而不是交互式 shell,Apt-get 会以不同方式处理它。同样,上面的“实验”证明这不是真的。

最佳答案

好吧,谜底解开了!感谢 Indian Linux Users Group 的热心人士.

这里的答案有两个——

首先,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 等还不可用时支持在系统安装期间下载文件。

其次,当您在运行 apt-get 后按 Ctrl-C 时,SIGINT 会发送到 http,而不是 apt-get。当 http 收到 SIGINT 时,它会在关闭前保存下载状态。

这是完美运行的更新脚本 -

#!/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

关于bash - 当您执行 Ctrl-C 时 BASH 中会发生什么(提示,它不仅仅是发送 SIGINT),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6624622/

相关文章:

linux - 如何拆分一个大变量?

javascript - 在 NodeJS CLI 应用程序中将参数传递给可执行文件

linux - 用于区分 linux 中的服务帐户和用户帐户的脚本

linux - 在 USR1 信号后可靠地终止 sleep 进程

linux - 在 linux bash 脚本中杀死一个 10 分钟的老僵尸进程

c++ - 通过 `kill`生成的SIGSEGV是否特殊?

bash - 使用 bash 打开和关闭进程

ios - iPhone 应用程序终止进程

python - 为什么这种Python多线程方法比单线程方法需要更多的时间来解决相同的任务?

android - 谁能解释一下ActivityManager : Start proc 27854 (class)/u0a66 for service?