O que significa anexar um processo a um terminal? [fechadas]

1

Estou aprendendo Linux. Surgiu a ideia de que um processo pode ser anexado a um terminal. O que significa anexar um processo a um terminal (TTY) e por que eu desejaria fazê-lo?

    
por flashburn 16.09.2017 / 08:47

1 resposta

3

OBSERVAÇÃO: Para uma boa cartilha sobre controle de trabalho no Unix, eu o direcionaria para a página da Wikipedia sobre o tópico - Controle de tarefas (Unix) .

Terminal conectado?

A frase "anexado ao terminal" normalmente é o que você ouvirá ao falar sobre tarefas em um contexto de shell. Mas tem outros significados. a frase "anexar um processo a um terminal" também pode significar usar uma ferramenta como gdb ou strace ou lsof para anexar a um ID de processo específico (PID) e listar informações ou monitorá-lo.

Vou discutir os dois, mas, para começar, vou cobrir as filas de trabalho, já que suspeito que seja esse que você está procurando.

Plano de fundo - filas de trabalho

Em sistemas operacionais semelhantes a Unix, você normalmente verá o conceito de jobs. Na maioria dos sistemas operacionais do tipo Unix que eu usei, todos eles geralmente funcionam de maneira similar. Ou seja, eles podem ser colocados em segundo plano e atribuídos a um número em uma fila (fila de trabalhos) e podem ser acionados a partir do contexto de seu número nessa fila de trabalhos.

Para colocar algo na fila de trabalhos, eles normalmente chamam esse ato de background. Quando você retoma um trabalho com plano de fundo, você chama esse primeiro plano. Os comandos para fazer isso são bg e fg normalmente. Você também pode colocar trabalhos no plano de fundo imediatamente usando o% amperes& no final de qualquer comando executado.

Exemplos

empregos

$ sleep 2 &
[1] 19189

Aqui estou executando um comando sleep por 2 segundos e colocando em segundo plano. A saída fornece imediatamente informações úteis, como o número da fila de trabalhos ( [1] ) e o ID do processo do trabalho em segundo plano, 19189.

Quando esse trabalho terminar, ele imprimirá esse tipo de mensagem no terminal de onde ele foi executado:

$
[1]+  Done                    sleep 2

primeiro plano & fundo

Para atuar em trabalhos com experiência:

$ sleep 20 &
[1] 19207

$ fg
sleep 20
^C

Aqui eu enviei um trabalho para o segundo plano ( & ), depois o trouxe de volta para o primeiro plano ( fg ) e depois o matei com o Ctrl + C Comando ( ^C ).

Se tivéssemos vários trabalhos em segundo plano:

$ sleep 20 &
[1] 19224
$ sleep 20 &
[2] 19225
$ sleep 20 &
[3] 19226
$ jobs
[1]   Running                 sleep 20 &
[2]-  Running                 sleep 20 &
[3]+  Running                 sleep 20 &

Podemos vê-los com o comando jobs . Observe o pouco + e - ao lado de # 3 e # 2. Se eu executar o comando fg sem especificar um número da fila de trabalhos, receberei o último trabalho que foi colocado na fila de tarefas ( + ). Por exemplo:

$ fg
sleep 20
^C

$ jobs
[1]-  Running                 sleep 20 &
[2]+  Running                 sleep 20 &

matando

Você pode usar os números da fila de trabalhos para atuar nos trabalhos. Um desses métodos é matá-los. Para se referir ao número de uma fila de trabalhos, você os prefixará com um % quando quiser se referir a eles com outros comandos, como kill . Você pode, é claro, kill múltiplo de uma só vez, ou apenas um:

$ kill %3 %4 %5
$ jobs
[3]   Terminated              sleep 20
[4]   Terminated              sleep 20
[5]-  Terminated              sleep 20
[6]+  Running                 sleep 20 &

Background anexando a um PID

Para anexar um processo a um terminal também pode significar o seguinte. Aqui está o PID do meu shell:

$ echo $$
23543

Em outro shell, estou executando strace e conectando a este processo para ver o que o sistema está chamando:

$ strace -p 23543
strace: Process 23543 attached
read(0,

OBSERVAÇÃO: Aqui você pode ver que está aguardando em um read para comandos. Isso é o que terminais / shells fazem.

Aqui podemos ver que eu comecei a digitar o comando ls dentro dele, e o shell está ecoando este backout para o shell na forma de write() system calls.

read(0, "l", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "l", 1)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "s", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "s", 1)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0,

Esta é outra forma de anexar um processo a um terminal.

Outras formas

Uma das referências mais obscuras para anexar um processo a um terminal pode ser assumida aqui também. Este U & L Q & A intitulado: Como anexar terminal ao processo separado ? abrange aquele em todas as suas formas.

A premissa básica com essa forma de referência é que você assumiu um trabalho de segundo plano e "desconectou-o" do shell atual. Você faz isso usando os comandos nohup ou disown .

Depois que um processo for rejeitado, você não poderá mais usar os comandos jobs , fg ou bg para agir sobre ele. Não está mais associado ao PID do seu shell atual.

O método tradicional para readquirir um processo anteriormente desconhecido é usar uma ferramenta como reptyr , que irá anexar novamente um PID ao seu shell existente. Por exemplo, digamos que iniciamos 2 jobs e nohup deles:

$ nohup sleep 200 &
[1] 19720
$ nohup sleep 200 &
[2] 19721

Ainda anexado à fila de trabalhos do nosso terminal, vamos disown deles:

$ jobs
[1]-  Running                 nohup sleep 200 &
[2]+  Running                 nohup sleep 200 &
$ disown -a

Agora eles se foram:

$ jobs
$

Eles ainda estão listados como sendo filhos do PID do nosso shell original (23543):

$ ps -eaf|grep -E "19720|19721"
vagrant  19720 23543  0 18:29 pts/1    00:00:00 sleep 200
vagrant  19721 23543  0 18:29 pts/1    00:00:00 sleep 200

Agora, se sairmos e fizermos login novamente, veremos que esses processos agora estão listados como sendo pais do PID principal, 1:

$ ps -eaf|grep -E "19720|19721"
vagrant  19720     1  0 18:29 ?        00:00:00 sleep 200
vagrant  19721     1  0 18:29 ?        00:00:00 sleep 200

Esses processos conseguiram fazer isso porque nohup deles e disown deles. Vamos recolocar um deles:

$ reptyr -s 19720
[-] Timed out waiting for child stop.

^C

NOTA: No exemplo acima, eu recoloquei o PID 19720 no meu shell e depois o matei via Ctrl + C . Nós podemos ver que agora se foi:

$ ps -eaf|grep -E "19720|19721"
vagrant  19721     1  0 18:29 ?        00:00:00 sleep 200
    
por 09.08.2018 / 23:59