Como usar / enviar sinais na linha de comando, para qualquer programa (por exemplo, dd)

2

Estou tentando entender a manpage do programa dd , que menciona:

Sending a USR1 signal to a running 'dd' process makes it print I/O statistics to standard error and then resume copying.

         $ dd if=/dev/zero of=/dev/null& pid=$!
         $ kill -USR1 $pid; sleep 1; kill $pid

O que significa pid=$! ?

Esta é uma atribuição de uma variável, que obtém o pid de dd ? E é eventualmente usado na variável $pid ?

Além disso, por que eles usam sleep e kill ?

Esta é a maneira de usar -USR1 ?

    
por Aby W 24.10.2016 / 13:42

3 respostas

4

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

O trailing & significa executar o comando prefix em segundo plano. (Aviso: Esta é uma declaração simplista)

Consulte este :

$! is the PID of the most recent background command.

Portanto, pid=$! atribui o PID de plano de fundo mais recente à variável pid, que é dd PID.

Also why they use sleep and kill?.

Você precisa de kill $pid (se não for especificado o parâmetro, o sinal padrão para kill é TERM que é a finalização do processo) para finalizar o processo dd após o teste, caso contrário o processo dd apenas fique em segundo plano e exaure seus recursos de CPU. Verifique o seu monitor de sistema da sua plataforma para ver.

Considerando que Kill -USR1 $pid imprime estatísticas de E / S, não encerra o processo.

Sem dormir por 1 segundo, seu processo dd pode ser finalizado pela última instrução de comando kill $pid ** antes de ter a chance de gravar a saída de estatísticas em seu terminal. Os processos são síncronos, mas trap + operação de gravação ( kill -USR1 $pid ) pode ser mais lenta que finalizar operação ( kill $pid ). Então, sleep 1 segundo para atrasar a inicialização de kill $pid para garantir a impressão da saída de estatísticas.

This is the way to use -USR1?

Apenas man dd :

Sending a USR1 signal to a running 'dd' process makes it print I/O statistics to standard error and then resume copying.

e man 7 signal :

   SIGUSR1   30,10,16    Term    User-defined signal 1
   SIGUSR2   31,12,17    Term    User-defined signal 2

Combine as duas instruções, você deve entender que USR1 é Sinal definido pelo usuário definido por dd para fornecer uma maneira de o usuário interrompê-lo e imprimir estatísticas de E / S na mosca. É um manipulador específico do programa, isso não significa que você pode kill -USR1 other_program_pid e esperar resultados de estatísticas.

Você também pode se interessar por esta: Por que o SIGUSR1 causa processo a ser finalizado? .

    
por 24.10.2016 / 14:18
5

Esta é apenas uma demonstração para ilustrar o uso do sinal USR1 com dd .

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

inicia dd em segundo plano, copiando os dados de /dev/zero (que produz zeros sempre que um programa lê) para /dev/null (que descarta qualquer coisa escrita nele). Isso fornece uma instância inofensiva do dd , que pode ser usada para experimentar - ele não usa nenhum armazenamento e continuará funcionando enquanto quisermos, o que dá ao usuário tempo para enviar sinais para ele.

pid=$!

armazena o identificador de processo do último comando de segundo plano ( $! ) na variável pid .

kill -USR1 $pid

envia o sinal USR1 para o processo cujo identificador é o valor armazenado na variável pid , o fundo dd neste caso. Quando dd recebe este sinal, imprime seu progresso atual (a quantidade de dados lidos e gravados) e continua copiando.

sleep 1

aguarda um segundo.

kill $pid

envia o sinal TERM para dd , o que faz com que dd saia. (Não faz sentido deixar o background dd rodando aqui.)

Seria mais instrutivo executar isso do que a segunda linha acima:

kill -USR1 $pid; sleep 1; kill -USR1 $pid; kill $pid

Isso produziria o progresso duas vezes, com um segundo entre eles, para mostrar o progresso de dd ; então mate dd sem esperar.

Para uso real, você especificaria entradas e saídas apropriadas para o comando dd original e, provavelmente, também algumas outras opções, e você não executaria a última kill - esperaria por dd para terminar por conta própria.

Para responder à sua pergunta final, é assim que você envia os sinais USR1 de um shell (ou qualquer outro sinal): você usa kill com o sinal que você deseja enviar e os identificadores de processo (ou identificadores de trabalho) dos processos para os quais você deseja enviar o sinal. Outros comandos (não POSIX) que você pode usar são pkill e killall , quando você quiser encontrar processos pelo nome.

    
por 24.10.2016 / 13:56
2

Para a maioria ou todos os shells, $! é o ID do processo (também chamado PID) do último processo que o shell bifurcou. O comando dd foi bifurcado com & , de modo que pid=$! logo após bifurcar dd atribui dd ID do processo à variável pid .

Um ID de processo é um número usado pelo Linux ou Unix para se referir a um espaço de endereço com algum código em execução nele.

O programa kill tem um nome não intuitivo, porque seu propósito é enviar sinais (mensagens pequenas e assíncronas) para os processos. Existem apenas alguns sinais, talvez 128 no total, eles têm números e nomes. O sinal "kill" é o número 9, por exemplo. USR1 é definido como o número 10. Assim, o kill -USR1 $pid envia o sinal 10 para o processo numerado $pid . dd às vezes leva muito tempo para ser executado, então é quase certamente o ID do processo do comando dd que foi bifurcado anteriormente e foi executado em segundo plano. O comando kill $pid envia um sinal TERM para esse mesmo ID de processo. TERM significa "terminar". Programas bem escritos costumam pegar o TERM, limpar os recursos que eles alocaram e depois sair.

Não sei bem por que você executaria dd em segundo plano, enviaria um sinal USR1 para ele, esperaria 1 segundo e, em seguida, faria com que dd desalocasse todos os recursos e saísse. O fragmento de código inteiro parece assumir que dd é executado por um longo tempo, o que pode não ser verdade. Eu acho que existem condições de corrida neste código, e qualquer que seja a semântica desejada, você pode não obtê-las.

    
por 24.10.2016 / 14:01