killing - disown process bash
Qué sucede en BASH cuando haces Ctrl-C(sugerencia, no es simplemente enviar un SIGINT) (3)
Sugerencia, no es simplemente enviar un SIGINT).
Sí, solo está enviando un SIGINT
:-) Estrangular es lo que está sucediendo, usted tiene ese derecho. Esto es lo que sospecho que está sucediendo:
Algo está limitando el ancho de banda de las conexiones . Para rastrear conexiones, también incluye el puerto de origen (que es una mala idea IMO) entre otros parámetros
Cuando matas a apt-get y lo reinicias, naturalmente obtendrás un nuevo puerto de origen TCP y la entidad maligna estrangulandote pensarás, " Oh, es una nueva conexión ", que en realidad es
Entonces, ¿cómo acelerar las cosas? Bueno, la verdadera solución sería usar múltiples descargas paralelas. Nunca lo usé yo mismo, pero he oído hablar de una herramienta llamada "apt-fast" (en realidad es un script bash) que hace algo como esto.
EDITAR
Después de leer la pregunta nuevamente, sospecho que la señal no se envía a apt-get
.
sudo apt-get install foo -y &
sudo kill -2 $! # sends signal to sudo, which sends whatever it wants to `apt-get`
Entonces creo que sudo
capta la señal y envía algo más (sigterm? Sighup?) A apt-get
.
Primero, un poco de fondo: cuando apt-get install
descargas de apt-get install
de Internet de mi empresa, proporciona una gran velocidad (400-500 KB / s) durante los primeros 10 segundos, antes de bajar a una décima parte (40-50 KB). / s), y luego después de unos minutos a un verdaderamente miserable (4-5KB / s). Esto me hace pensar que el sysadmin ha implementado algún tipo de esquema de estrangulamiento de red.
Ahora sé que la red no es simplemente errática, porque si comienzo un apt-get install foo
, Ctrl-C
después de 10 segundos e inmediatamente ejecuto apt-get install foo
nuevamente (haciendo una flecha hacia arriba e intro para usar el historial de bash ), y luego repita este proceso durante unos minutos hasta que se hayan descargado todos los paquetes ; puedo descargar incluso paquetes grandes muy rápido. En particular, incluso después de abortar una descarga con Ctrl-C, apt-get parece poder reanudar la descarga en la siguiente invocación.
Por supuesto, mirar la pantalla haciendo Ctrl-C Arriba Entrar cada 10 segundos se vuelve muy aburrido muy rápido, así que escribí un guión de shell -
#!/bin/sh
for i in `seq 1 100` ; do
sudo apt-get install foo -y &
sleep 10
sudo kill -2 $!
done
Esto parece funcionar Genera apt-get, lo ejecuta durante 10 segundos y luego mata (mediante el envío de un SIGINT) y lo inicia de nuevo. Sin embargo, realmente no funciona porque ahora apt-get no reanuda las descargas en invocaciones posteriores.
Un experimento que realicé sudo apt-get install foo
desde un terminal y luego ejecuté kill -2 <PID of apt-get>
desde otro terminal. E incluso en ese caso, cuando reinicio apt-get, no reanuda la descarga.
Entonces, claramente, una Ctrl-C no es equivalente a SIGINT. Y algo más está sucediendo cuando hago Ctrl-C manualmente, lo que le da a apt-get la oportunidad de guardar el estado de la descarga. La pregunta es: ¿qué es?
Editar
Estas son las sugerencias que he recibido hasta ahora, pero no puros. ¡El misterio se profundiza! -
En
sudo kill -2 $!
la señal podría ir asudo
lugar deapt-get
. Esta no es la razón porque, como mencioné anteriormente, también intenté enviar SIGINT específicamente al PID de apt-get e incluso eso impidió que apt-get guardara su estado.Sudo capta la señal y envía otra señal a apt-get. Intenté enviar apt-get todas las señales que puedo pensar! Todavía no reanuda la descarga de ninguno de ellos. Solo reanuda las descargas cuando hago Ctrl-C para matarlo.
Apt-get maneja SIGINT de forma diferente si se trata de un script en lugar de un shell interactivo. Nuevamente, el "experimento" anterior demuestra que esto no es cierto.
Bien, ¡misterio resuelto! Gracias a la gente amable del Indian Indian Users Group .
La respuesta aquí es doble:
En primer lugar, apt-get
invoca otro programa llamado http
para descargar datos.
[~] ➔ 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
Tenga en cuenta que se trata de un ejecutable, ni siquiera una secuencia de comandos, probablemente para permitir la descarga de archivos durante la instalación del sistema cuando aún no están disponibles ninguno de perl / python / ruby, etc.
En segundo lugar, cuando presiona Ctrl-C después de ejecutar apt-get
, el SIGINT se envía a http
, y no a apt-get
. Cuando http
recibe el SIGINT, guarda el estado de descarga antes de apagarse.
Aquí está el script actualizado que funciona perfectamente -
#!/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
De acuerdo, como dijo Cnicutar , solo está enviando un SIGINT. Ahora, la clave de lo que se dijo está aquí:
Sospecho que la señal no se envía a apt-get
cual es verdad. Dejame explicar.
Al ejecutar sudo foo
inicia un proceso de sudo
que luego (es decir, después de insertar su contraseña) invoca foo
; es un argumento Una vez que sudo
acepta el passwd e invoca foo
, estás en el " espacio " de foo
. Lo que sea que hagas mientras esperas que termine foo
se hace en foo
y no en sudo.
Entonces, al enviar una Ctrl C mientras espera que apt
haga su trabajo, esa señal se envía a apt
.
Ahora, si comienzas sudo
, su pid se almacena en $!
var. Enviar una señal de kill
a ese pid / var es enviar una señal de kill
a sudo
, no apt
que luego fue iniciada por sudo. Si quieres enviar una señal de kill
a apt
, probablemente quieras usar la utilidad pidof
.
Pruebe usted mismo:
sudo do-something
echo $!
pidof do-something
la salida debe ser dos pid diferentes.
Espero que eso ayude un poco.