Posso nohup / rastrear um processo já iniciado?

260

Estou fazendo algumas execuções de teste de scripts de migração de dados de longa execução, sobre SSH. Digamos que eu comece a executar um script por volta das 16h; agora, 18:00, e eu estou me xingando por não fazer isso tudo screen.

Existe alguma maneira de "retroativamente" nohupum processo ou preciso deixar meu computador online a noite toda? Se não é possível anexar screena / nohupum processo que eu já iniciei, por que? Algo a ver com a interação entre pai e filho? (Não aceitarei uma resposta "não" que não atenda ao menos a pergunta 'por que' - desculpe;)

ojrac
fonte
4
Só vi um post interessante sobre o blog disown. blogs.oracle.com/ksplice/entry/disown_zombie_children_and_the
ojrac

Respostas:

212

Se você estiver usando o Bash, poderá executar disown -h job

renegar

disown [-ar] [-h] [jobspec ...]

Sem opções, cada especificação de trabalho é removida da tabela de tarefas ativas. Se a -hopção for dada, o trabalho não será removido da tabela, mas será marcado para que o SIGHUP não seja enviado ao trabalho se o shell receber um SIGHUP. Se o jobspec não estiver presente e nem a opção -anem -rfor fornecida, o job atual será usado. Se nenhum jobpec for fornecido, a -a opção significa remover ou marcar todos os jobs; a -ropção sem o argumento jobspec restringe a operação à execução de jobs.

gharper
fonte
Impressionante; Eu esperava que algo assim aparecesse.
ojrac
7
A vida pode ser injusta. gharper e me foram postando isso em aproximadamente o mesmo tempo :)
serverhorror
4
Você é meu herói
Thomas Dignan
9
renegar não é específico para o bash. É também em zsh, ksh93, ...
Phil P
2
Eu achei que você realmente tem que usar disown %1se 1 é o jobspec, ao contrário fg ou bg em que você acabou de usar bg 1 serverwatch.com/tutorials/article.php/3935306/...
mltsy
81

Use reptyr

No README:

reptyr - A tool for "re-ptying" programs.
-----------------------------------------

reptyr is a utility for taking an existing running program and
attaching it to a new terminal. Started a long-running process over
ssh, but have to leave and don't want to interrupt it? Just start a
screen, use reptyr to grab it, and then kill the ssh session and head
on home.

USAGE
-----

  reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your
current terminal.

After attaching, the process will take input from and write output to
the new terminal, including ^C and ^Z. (Unfortunately, if you
background it, you will still have to run "bg" or "fg" in the old
terminal. This is likely impossible to fix in a reasonable way without
patching your shell.)

Algumas postagens de blog de seu autor:

Jonathan Tran
fonte
Vou ficar com as ferramentas internas (ou seja, deserdadas), mas não é tão flexível quanto a reptyr. +1
ojrac
22

Para roubar um processo de um tty para o tty atual, convém tentar este hack:

http://www.ucc.asn.au/~dagobah/things/grab.c

Ele precisa de reformatação para compilar as versões atuais do Linux / glibc, mas ainda funciona.

Juliano
fonte
1
Excepcionalmente legal.
ojrac
16

Quando um processo é iniciado, STDIN, STDOUT e STDERR são conectados a alguma coisa . Geralmente você não pode mudar isso depois que o comando é iniciado. No caso que você está descrevendo, provavelmente é um tty associado à sessão ssh. nohup praticamente só faz ...

command < /dev/null > nohup.out 2>&1

Ou seja, define STDIN como / dev / null, STDOUT como um arquivo e STDERR como STDOUT. A tela faz coisas muito mais sofisticadas, envolvendo a configuração de ttys que se dirigem a si mesma.

Não conheço nenhuma maneira de retroceder retroativamente ou rastrear um processo em execução. Se você cd para / proc / $ pid / fd e vê o que 0, 1 e 2 apontam.

Você pode ter alguma sorte com rejeição, mas não se o processo tentar fazer algo com STDIN, STDOUT ou STDERR.

freiheit
fonte
2
+1 nos bons comentários. st (din | out | err) é a outra metade do problema, e agradeço os conselhos sobre por onde começar a procurar, da próxima vez que estiver nessa confusão.
ojrac
6
Você realmente pode alterá-lo na maioria dos Unixes. É um truque nojento. Eu amo isso. :) O que você faz é conectar-se ao processo usando o suporte a depuração como ptrace e forçar o processo a chamar dup2 () para reconectar 0,1,2 a outro manipulador de arquivo.
Zan Lynx
2
Sim, você pode mudar. Envolve pausar o processo (SIGSTOP) e modificar os descritores de arquivo para fd 0, 1, 2. Em seguida, reinicie (SIGCONT).
Michael Martinez
13

Cryopid é um desenvolvimento adicional do autor do grab.c que congela um processo em um arquivo, que você executa (dentro da tela) para retomar o processo.

TRS-80
fonte
1
Agradável! Tentei usar o cryopid na dissertação de mestrado sobre migração de processos, mas ela falhou o tempo todo, não importa o que eu fiz. No final, eu tive que usar o dynckpt com uma versão antiga do Linux. Você talvez esteja envolvido no desenvolvimento de crióides? Vejo que seu nome é semelhante ao domínio do autor.
Juliano
1
Não estou envolvido no desenvolvimento, apenas conheço o autor da universidade. Ele não tem o tempo para manter cryopid no momento, por isso parece que algumas pessoas começaram a trabalhar nele em sharesource.org/project/cryopid
TRS-80
12

Só posso lhe dar um simples "Não" sem o porquê da parte da tela, eu estaria interessado na razão de você.

No entanto, você tentou disown(um bash embutido)

~ $ echo $SHELL
/bin/bash
~ $ type disown
disown is a shell builtin
~ $ help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.
serverhorror
fonte
5

Recentemente, vi um link para o neercs , que é um utilitário semelhante a uma tela criado usando a libcaca, uma biblioteca de arte ascii colorida. Entre outros recursos, ele possui a capacidade de capturar um processo existente e reimplantá-lo dentro de sua sessão neercs (tela).

No entanto, eu não o usei, portanto não posso comentar se funciona ou não.

Daniel Lawson
fonte
2

Provavelmente estou pensando mal, então sinta-se à vontade para me corrigir (eu já aprendi sobre renúncia!) ... Um ctrl-Z e "bg" não funcionariam para pelo menos colocar o processo em execução em segundo plano? Ou é o principal problema que você ainda deseja ver STDOUT enquanto é executado?

Chris_K
fonte
1
Que ainda iria matar o processo quando o tty possuir morre assim que o OP precisa deixar a caixa onde ele intiated o comando em execução, que é o que ele quer evitar
serverhorror
OK, eu compro isso. Obrigada pelo esclarecimento. Então sugestões a renegar -h certo olhar muito mais inteligente do que a minha :-)
Chris_K
1
Você ainda pode fazer isso, logo após você teria que repudiar -h: stackoverflow.com/a/625436/705198
AndrewPK
2

Se você consegue viver sem conseguir interagir com o processo e não se opõe ao carregamento de módulos aleatórios do kernel, pode fazer pior do que olhar para o Snoop . Como alternativa, existem alguns outros projetos. Aqui está uma chamada de injcode, que pode fazer principalmente o que você deseja fazer.

David Pashley
fonte
1

Eu queria usar nohup(ou semelhante) para iniciar o linksnavegador de linha de comando e anexá-lo a ele depois de baixar um arquivo do site ASP.NET com um processo de autenticação complicado e muito estado de exibição oculta que dificultava o trabalho. com curl/ wget.

Finalmente acabei usando o tmuxque resolveu o trabalho simplesmente ótimo:

  1. Corre tmux
  2. Execute seu aplicativo ( linksno meu caso) e deixe em execução
  3. Feche a sessão SSH, o aplicativo continuará sendo executado
  4. Conecte-se ao SSH na mesma máquina posteriormente e execute tmux attachpara trazer o aplicativo de volta à tela
Dmitry Gusev
fonte
O tmux é ótimo - mas, como nohup ou tela, só funciona se você o usar antes de iniciar seu processo. Esta pergunta é sobre os momentos em que você percebe que precisa do tmux após o processo já estar em execução.
Ojrac
-1

Você está preocupado com o tempo limite da sessão? Nesse caso, você pode pressionar Ctrl-z e alterar o processo e, em seguida, colocar algo para manter a sessão ativa como um "ping-t localhost" ou "top".

Se você deseja fazer logout, receio que não possa adicionar outros comentários.

TrojanName
fonte
É a coisa do logout.
ojrac
1
Outra maneira de impedir a desconexão é correr em cima. Isso está sempre embaralhando alguns bytes.
Rory