Intento entender la página de manual del dd
programa, que menciona:
Enviar una señal USR1 a un proceso 'dd' en ejecución hace que imprima estadísticas de E/S con un error estándar y luego reanude la copia.
$ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid
¿Que pid=$!
significa?
¿Es esta una asignación de una variable, que obtiene el pid de dd
? ¿Y finalmente se usa en la $pid
variable?
Además, ¿por qué usan sleep
y kill
?
¿Es esta la forma de usarlo -USR1
?
Respuesta1
dd if=/dev/zero of=/dev/null&
El final &
significa ejecutar el comando de prefijo en segundo plano. (Descargo de responsabilidad: esta es una declaración demasiado simplificada)
Referirse aeste:
$! es el PID del comando en segundo plano más reciente.
Así que pid=$!
asigna elPID de fondo más recientea la variable pid, que es dd
PID.
Además ¿por qué usan dormir y matar?
Necesitaskill $pid
(si no se especifica el parámetro, la señal predeterminada para matar es TERM, que es la terminación del proceso)para finalizar el dd
proceso después de haber terminado las pruebas; de lo contrario, dd
el proceso puede permanecer en segundo plano y agotar los recursos de su CPU. Verifique el monitor del sistema de su plataforma para ver.
Mientras que Kill -USR1 $pid
imprime estadísticas de E/S, no finaliza el proceso.
Sin dormir 1 segundo, su dd
proceso puede terminar con la última declaración de comando kill $pid
** antes de tener la oportunidad de escribir la salida de estadísticas en su terminal. Los procesos son sincrónicos perooperación trampa+escritura( kill -USR1 $pid
) puede ser más lento queterminar la operación( kill $pid
). Entonces, sleep 1
en segundo lugar, retrasar el inicio kill $pid
para garantizar que la salida de estadísticas se haya impreso.
¿Esta es la forma de utilizar -USR1?
Justo man dd
:
Enviar una señal USR1 a un proceso 'dd' en ejecución hace que imprima estadísticas de E/S con un error estándar y luego reanude la copia.
Y man 7 signal
:
SIGUSR1 30,10,16 Term User-defined signal 1 SIGUSR2 31,12,17 Term User-defined signal 2
Combine ambas declaraciones, debe comprender que USR1 esSeñal definida por el usuarioque se define por dd
proporcionar una forma para que el usuario lo interrumpa yimprimir estadísticas de E/Ssobre la marcha. Es un controlador específico del programa, no significa que pueda kill -USR1 other_program_pid
esperar resultados estadísticos.
También te puede interesar sobreesto: ¿Por qué SIGUSR1 hace que el proceso finalice?.
Respuesta2
Esta es sólo una demostración para ilustrar el uso de la USR1
señal con dd
.
dd if=/dev/zero of=/dev/null &
comienza dd
en segundo plano, copiando datos de /dev/zero
(lo que produce ceros cada vez que un programa lee) a /dev/null
(lo que descarta todo lo escrito en él). Esto proporciona una instancia inofensiva dd
que se puede usar para experimentar: no consume almacenamiento y seguirá ejecutándose todo el tiempo que queramos, lo que le da al usuario tiempo para enviarle señales.
pid=$!
almacena el identificador de proceso del último comando en segundo plano ( $!
) en la variable pid
.
kill -USR1 $pid
envía la USR1
señal al proceso cuyo identificador es el valor almacenado en la pid
variable, el fondo dd
en este caso. Cuando dd
recibe esta señal, imprime su progreso actual (la cantidad de datos leídos y escritos) y continúa copiando.
sleep 1
espera un segundo.
kill $pid
envía la TERM
señal a dd
, lo que provoca dd
la salida. (No tiene sentido dejar el fondo dd
ejecutándose aquí).
Sería más instructivo ejecutar esto en lugar de la segunda línea anterior:
kill -USR1 $pid; sleep 1; kill -USR1 $pid; kill $pid
Esto generaría el progreso dos veces, con un segundo entre ellas, para mostrar dd
el progreso; Luego mata dd
sin esperar.
Para el uso real, especificaría entradas y salidas apropiadas para el dd
comando original, y probablemente también algunas otras opciones, y no ejecutaría la última kill
; esperaría a dd
que termine por sí sola.
Para responder a tu pregunta final, así es como envías USR1
señales desde un caparazón (o cualquier otra señal): usaskill
con la señal que desea enviar y los identificadores de proceso (o identificadores de trabajo) de los procesos a los que desea enviar la señal. Otros comandos (no POSIX) que puede utilizar sonpkill
ykillall
, cuando desea buscar procesos por nombre.
Respuesta3
Para la mayoría o todos los shells, $!
es el ID del proceso (también llamado PID) del último proceso que el shell bifurcó. El dd
comando se bifurcó con &
, de modo que pid=$!
justo después de la bifurcación dd
se asigna dd
el ID del proceso a la variable del shell pid
.
Un ID de proceso es un número utilizado por Linux o Unix para hacer referencia a un espacio de direcciones en el que se ejecuta algún código.
El kill
programa tiene un nombre poco intuitivo, porque su propósito es enviar señales (pequeños mensajes asíncronos) a los procesos. Sólo hay unas pocas señales, quizás 128 en total, tienen números y nombres. La señal de "matar" es la número 9, por ejemplo. USR1 se define como el número 10. Entonces kill -USR1 $pid
envía la señal 10 al proceso numerado $pid
. dd
a veces lleva mucho tiempo ejecutarlo, por lo que es casi seguro que sea el ID del proceso del dd
comando que se bifurcó anteriormente y se ejecutó en segundo plano. El kill $pid
comando envía una señal TERM a ese mismo ID de proceso. TERM significa "terminar". Los programas bien escritos generalmente capturan TERM, limpian los recursos que han asignado y luego salen.
No estoy del todo seguro de por qué se ejecutaría dd
en segundo plano, le enviaría una señal USR1, esperaría 1 segundo y luego dd
desasignaría todos los recursos y saldría. Todo el fragmento de código parece suponer que dd
se ejecuta durante mucho tiempo, lo que puede no ser cierto. Creo que hay condiciones de carrera en este código y, cualquiera que sea la semántica deseada, es posible que en realidad no las obtengas.
Respuesta4
Si espera que dd
el comando se ejecute en primer plano y muestre el estado de progreso actual. intente ejecutar el comando con status=progress
la bandera:
sudo dd if=/dev/sda of=/dev/sdb status=progress
Esto mostrará dinámicamente el progreso.
Esa es una extensión de la implementación de GNU dd
(agregada en la versión 8.24 lanzada en 2015), también disponible en la dd
implementación en FreeBSD desde 12.0 (2018), pero generalmente no en otras implementaciones, incluidas otras BSD.