Questão Como faço para destacar um processo do Terminal inteiramente?


Eu uso o Tilda (terminal drop-down) no Ubuntu como meu "comando central" - basicamente como os outros podem usar o GNOME Do, Quicksilver ou Launchy.

No entanto, estou com dificuldades para separar completamente um processo (por exemplo, Firefox) do terminal em que foi lançado - ou seja, impedir que tal processo (não) filho

  • é encerrado ao fechar o terminal de origem
  • "polui" o terminal de origem via STDOUT / STDERR

Por exemplo, para iniciar o Vim em uma janela de terminal "apropriada", tentei um script simples como o seguinte:

exec gnome-terminal -e "vim $@" &> /dev/null &

No entanto, isso ainda causa poluição (também, passar um nome de arquivo não parece funcionar).


274


origem


Essa também é uma boa pergunta. Eu acho que é justo considerar Bash uma linguagem de programação - embora de fato o escopo desta questão seja provavelmente mais do lado do sysadmin ...
Esta é uma duplicata desta questão stackoverflow.com/questions/285015/… - Dana the Sane
dup de:superuser.com/questions/177218/… - behrooz
Seu caso de uso não descreve o desapego completo, por si só. - jiggunjer


Respostas:


Em primeiro lugar; Depois de iniciar um processo, você pode fazer o plano de fundo parando-o primeiro Ctrl-Z) e depois digitando bg para deixá-lo retomar em segundo plano. Agora é um "trabalho" e sua stdout/stderr/stdin ainda estão conectados ao seu terminal.

Você pode iniciar um processo como plano de fundo imediatamente acrescentando um "&" ao final dele:

firefox &

Para executá-lo em segundo plano silenciado, use isto:

firefox </dev/null &>/dev/null &

Algumas informações adicionais:

nohup é um programa que você pode usar para executar seu aplicativo com de modo que seu stdout / stderr possa ser enviado para um arquivo e tal que fechar o script pai não irá SIGHUP o filho. No entanto, você precisa ter a perspicácia de usá-lo antes de iniciar o aplicativo. Por causa do caminho nohup funciona, você não pode simplesmente aplicá-lo a um processo em execução.

disown é um bash embutido que remove um trabalho de shell da lista de trabalhos do shell. O que isso basicamente significa é que você não pode usar fg, bg sobre isso, mas mais importante, quando você fecha o seu shell não vai travar ou enviar um SIGHUP para aquela criança mais. Ao contrário nohup, disown é usado depois de o processo foi lançado e passado por segundo plano.

O que você não pode fazer, é alterar o stdout / stderr / stdin de um processo depois de ter lançado. Pelo menos não da casca. Se você iniciar seu processo e informar que seu stdout é seu terminal (que é o que você faz por padrão), então esse processo é configurado para saída para seu terminal. Seu shell não tem nenhum negócio com a configuração do FD dos processos, que é puramente algo que o próprio processo gerencia. O processo em si pode decidir se deseja fechar seu stdout / stderr / stdin ou não, mas você não pode usar seu shell para forçá-lo a fazê-lo.

Para gerenciar a saída de um processo em segundo plano, você tem muitas opções de scripts, "nohup" provavelmente sendo o primeiro a se lembrar. Mas para processos interativos você começa, mas esquece de silenciar (firefox < /dev/null &>/dev/null &você não pode fazer muito, realmente.

Eu recomendo que você receba o GNU screen. Com a tela você pode apenas fechar o seu shell em execução quando a saída do processo se tornar um incômodo e abrir um novo (^Ac).


Ah, e a propósito, não use "$@"onde você está usando.

$@significa, $1, $2, $3 ..., o que transformaria seu comando em:

gnome-terminal -e "vim $1" "$2" "$3" ...

Isso provavelmente não é o que você quer, porque só toma 1 argumento. Usar $1 para mostrar que seu script só pode manipular um argumento.

É muito difícil conseguir vários argumentos funcionando adequadamente no cenário que você deu (com o gnome-terminal -e) Porque -e leva apenas um argumento, que é uma string de comando do shell. Você teria que codificar seus argumentos em um. O melhor e mais robusto, mas um pouco desajeitado, é assim:

gnome-terminal -e "vim $(printf "%q " "$@")"

308



Muito obrigado por isso! Infelizmente, só posso aceitar uma resposta. Acabei com "nohup $ @ &> / dev / null &" e "alias wvim = 'launch.sh gnome-terminal -x vim'"
Que resposta fantasticamente detalhada e informativa. +1 - Teekin
@ Hi-Angel quando você fechar um bash shell interativo, bash HUPs todos os trabalhos ativos. Quando você ^ Z e bg um processo ainda é um trabalho, seja um plano de fundo. Para removê-lo como um trabalho, use disown, então o processo continuará vivo depois que você fechar o shell, já que o bash não vai mais usá-lo. - lhunath
Não vai usar $* ao invés de $@ corrigir o problema das seqüências separadas já? - sjas
O que você não pode fazer, é alterar o stdout / stderr / stdin de um processo depois de tê-lo lançado. - não é exatamente verdade. Usar reptyr por esta. - Stefan Seidel


nohup cmd &

nohup separa o processo completamente (daemoniza)


190



Embora sucinto seja valioso, a integridade é mais valiosa. Embora nohup seja um núcleoutil GNU, uma resposta apenas bash (ou uma nota sobre não ser um) seria apropriada aqui. Boa resposta, no entanto. - Limited Atonement
nohupapenas ignora o SIGHUP sinal. Executa o processo normalmente. Nenhuma daemonização. - nemo
@nemo O que significa que o processo não é desanexado, mas se tornaria desanexado (e um filho de init) se o shell saiu ... certo? - Noldorin
@Noldorin Sim. Ignorar o SIGHUP, que é enviado quando o shell termina, deixará o processo filho em execução e será realocado para o init. - nemo
O @nemo nohup também silencia as entradas / saídas padrão. Siga com disown para desanexar completamente. - jiggunjer


Se você estiver usando bash, experimentar disown [jobspec]; Vejo bash (1).

Outra abordagem que você pode tentar é at now. Se você não é superusuário, sua permissão para usar at pode ser restrito.


51



"disown" não parece ser um comando bash interno (não disponível na minha máquina e eu uso o bash). "nohup", como Ben sugeriu, pode ser uma maneira muito melhor (e padrão) de fazer isso.
nunca pensei em usar "at", obrigado pela idéia! - cadrian
at para delegar a execução para outra pessoa, eu gosto disso! +1 - Ninsuo
Como ponto de referência, isso funciona zsh também. - Coderer
Além disso, disown não parece ter o efeito desejado com gnome-terminal-disownprocessos ed ainda são mortos quando o terminal sai. Eu adoraria saber por que / como. - Kyle Strand


Lendo estas respostas, eu estava com a impressão inicial de que a emissão nohup <command> & seria suficiente. Correndo zsh no gnome-terminal, descobri que nohup <command> & não impediu que meu shell matasse processos filhos na saída. Apesar nohup é útil, especialmente com shells não interativos, só garante este comportamento se o processo filho não redefinir seu manipulador para o SIGHUP sinal.

No meu caso, nohup deveria ter evitado que sinais de desligamento atingissem o aplicativo, mas o aplicativo filho (neste caso, VMWare Player) estava redefinindo SIGHUP manipulador. Como resultado, quando o emulador de terminal é encerrado, ele ainda pode matar seus subprocessos. Isso só pode ser resolvido, no meu conhecimento, garantindo que o processo seja removido da tabela de jobs do shell. E se nohup é sobrescrito com um shell embutido, como às vezes é o caso, isso pode ser suficiente, no entanto, no caso em que não é ...


disown é um shell embutido bash, zshe ksh93,

<command> &
disown

ou

<command> &; disown

se você preferir one-liners. Isso geralmente tem o efeito desejável de remover o subprocesso da tabela de jobs. Isso permite que você saia do emulador de terminal sem acidentalmente sinalizar o processo filho. Não importa o que o SIGHUP manipulador parece, isso não deve matar seu processo filho.

Após o disown, o processo ainda é um filho do seu emulador de terminal (brincar com pstree se você quiser assistir isso em ação), mas depois que o emulador de terminal terminar, você deverá vê-lo anexado ao processo init. Em outras palavras, tudo é como deveria ser, e como você presumivelmente quer que seja.

O que fazer se o seu shell não suportar disown? Eu defendo fortemente a mudança para um que faz, mas na ausência dessa opção, você tem algumas opções.

  1. screen e tmux pode resolver este problema, mas eles são soluções de peso muito mais pesado, e eu não gosto de ter que executá-los para uma tarefa tão simples. Eles são muito mais adequados para situações em que você deseja manter um tty, normalmente em uma máquina remota.
  2. Para muitos usuários, pode ser desejável ver se o seu shell suporta uma capacidade como a do zsh setopt nohup. Isso pode ser usado para especificar SIGHUPnão deve ser enviado para os trabalhos na tabela de trabalhos quando o shell sair. Você pode aplicar isso antes de sair do shell ou adicioná-lo à configuração do shell, como ~/.zshrc Se você sempre quiser.
  3. Encontre uma maneira de editar a tabela de trabalhos. Eu não consegui encontrar uma maneira de fazer isso tcsh ou csh, o que é um pouco perturbador.
  4. Escreva um pequeno programa em C para bifurcar e exec(). Esta é uma solução muito pobre, mas a fonte deve consistir apenas em uma dúzia de linhas. Você pode então passar comandos como argumentos de linha de comando para o programa C e, assim, evitar uma entrada específica do processo na tabela de jobs.

34





  1. nohup $ COMMAND &

  2. $ COMMAND & renegar

  3. comando setsid

Eu tenho usado o número 2 há muito tempo, mas o número 3 também funciona. Além disso, o disown possui um sinalizador 'nohup' de '-h', pode rejeitar todos os processos com '-a' e pode rejeitar todos os processos em execução com '-ar'.

O silenciamento é realizado por '$ COMMAND &> / dev / null'.

Espero que isto ajude!


23





Eu acho que a tela pode resolver seu problema


9





no tcsh (e talvez em outros shells também), você pode usar parênteses para separar o processo.

Compare isto:

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

Para isso:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

Isso remove o firefox da lista de empregos, mas ainda está vinculado ao terminal; se você logou neste nó via 'ssh', tentar sair ainda irá travar o processo ssh.


8





Para desassociar o comando tty shell run através de sub-shell para, e.

(comando)&

Quando a saída usou o terminal fechado, mas o processo ainda está ativo.

Verifica -

(sleep 100) & exit

Abra outro terminal

ps aux | grep sleep

O processo ainda está vivo.


6



Isso é exatamente o que eu precisava. Eu estava tentando adicionar um atalho de console para texto sublime e funciona perfeitamente, aqui está o que eu acabei com: ("/ opt / Sublime Text 2 / sublime_text" $ @) & - Ron E


Resposta mais simples e correta para o bash:

command & disown

Você não precisa separar o processo do terminal, mas do shell.


6



Funciona perfeitamente. Obrigado. - Royi