Cómo usar/enviar señales en la línea de comandos, para cualquier programa (por ejemplo, dd)

Cómo usar/enviar señales en la línea de comandos, para cualquier programa (por ejemplo, dd)

Intento entender la página de manual del ddprograma, 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 $pidvariable?

Además, ¿por qué usan sleepy 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 ddPID.

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 ddproceso después de haber terminado las pruebas; de lo contrario, ddel 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 $pidimprime estadísticas de E/S, no finaliza el proceso.

Sin dormir 1 segundo, su ddproceso 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 1en segundo lugar, retrasar el inicio kill $pidpara 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 ddproporcionar 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_pidesperar 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 USR1señal con dd.

dd if=/dev/zero of=/dev/null &

comienza dden 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 ddque 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 USR1señal al proceso cuyo identificador es el valor almacenado en la pidvariable, el fondo dden este caso. Cuando ddrecibe 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 TERMseñal a dd, lo que provoca ddla salida. (No tiene sentido dejar el fondo ddejecutá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 ddel progreso; Luego mata ddsin esperar.

Para el uso real, especificaría entradas y salidas apropiadas para el ddcomando original, y probablemente también algunas otras opciones, y no ejecutaría la última kill; esperaría a ddque termine por sí sola.

Para responder a tu pregunta final, así es como envías USR1señales desde un caparazón (o cualquier otra señal): usaskillcon 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 sonpkillykillall, 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 ddcomando se bifurcó con &, de modo que pid=$!justo después de la bifurcación ddse asigna ddel 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 killprograma 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 $pidenvía la señal 10 al proceso numerado $pid. dda veces lleva mucho tiempo ejecutarlo, por lo que es casi seguro que sea el ID del proceso del ddcomando que se bifurcó anteriormente y se ejecutó en segundo plano. El kill $pidcomando 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 dden segundo plano, le enviaría una señal USR1, esperaría 1 segundo y luego dddesasignaría todos los recursos y saldría. Todo el fragmento de código parece suponer que ddse 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 ddel comando se ejecute en primer plano y muestre el estado de progreso actual. intente ejecutar el comando con status=progressla 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 ddimplementación en FreeBSD desde 12.0 (2018), pero generalmente no en otras implementaciones, incluidas otras BSD.

información relacionada