Por que um trabalho de segundo plano com '| menos 'ser parado, enquanto o outro sem ele está funcionando?

5
$ pdfgrep -R -i spark . | less &
$ pdfgrep -R -i spark . &

$ jobs
[3]-  Stopped                 pdfgrep -R -i spark . | less
[4]   Running                 pdfgrep -R -i spark . &
  1. Por que aquele com | less será parado, enquanto o outro com sem que esteja funcionando?

    O trabalho em segundo plano parado não lê de stdin. Então isso não pode ser o motivo.

  2. A razão que eu fundo os trabalhos é que eu posso fazer algo mais na mesma sessão de terminal.

    O motivo pelo qual cano para less é porque não quero a saída stdout bagunça a tela da minha sessão de terminal quando estou fazendo outra coisa.

    Existe alguma maneira de alcançar os dois objetivos acima? Eu prefiro um pouco não salvar a saída em um arquivo sobre salvar a saída em um arquivo, porque é necessário um pouco mais para lembrar o arquivo, ler e excluí-lo.

Obrigado.

    
por Tim 08.10.2017 / 16:29

3 respostas

16

Vamos ver mais de perto o que está acontecendo com less :

$ pdfgrep -R -i spark . | strace less &
[...]
open("/dev/tty", O_RDONLY|O_LARGEFILE)  = 3
ioctl(3, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig -icanon -echo ...}) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGTTOU {si_signo=SIGTTOU, si_code=SI_KERNEL} ---
--- stopped by SIGTTOU ---

O controle de trabalho restringe os processos em um trabalho em segundo plano de executar determinadas operações no terminal de controle.

  • Se um processo em segundo plano tentar ler a partir do terminal, será enviado um sinal SIGTTIN , que normalmente interrompe (pausa) o processo.
  • Se um processo em segundo plano tentar definir os parâmetros de um terminal, será enviado um sinal SIGTTOU , que também normalmente interrompe o processo. Isso é o que está acontecendo aqui com o TCSETSW ioctl . O programa less tenta colocar o terminal em modo raw logo depois de iniciado, mesmo antes de saber se tem algo para exibir.

    Há uma boa razão para isso: você não deseja que um trabalho em segundo plano altere assincronamente seu terminal para que, por exemplo, o modo bruto esteja ativado e o eco esteja desativado. (Um processo em segundo plano pode obter parâmetros do terminal com TCGETS ioctl sem ser interrompido - veja a listagem acima.)

  • Se um processo em segundo plano tentar gravar no terminal e o terminal tiver o sinalizador tostop definido, será enviado o sinal SIGTTOU .

Você provavelmente não tem o sinalizador tostop definido (execute stty -a para verificar). Se você não fizer isso, um comando de fundo como pdfgrep -R -i spark . & que não altera as configurações do terminal poderá gravar no seu terminal sempre que ele tentar.

Você também escreveu:

The reason that I pipe to less is because I don't want the output to stdout messes up the screen of my terminal session when I am doing something else

O programa menos vai enviar a saída para o terminal, uma tela por vez. Se você executar stty tostop antes de pdfgrep | less & ou antes de pdfgrep & , eles só irão enviar para o seu terminal quando estiverem em primeiro plano.

    
por 08.10.2017 / 20:55
6

Para responder à sua segunda pergunta: eu uso a tela (1) para multiplexar muitos comandos através de um dispositivo parecido com tty.

Existe pelo menos uma alternativa , o tmux (1) e um wrapper de simplificação para ambos, byobu (1).

    
por 08.10.2017 / 18:31
5

less está tentando interagir com (saída para) o TTY, mas como está sendo executado como um job em segundo plano, não possui TTY para gravar. O utilitário pdfgrep , por outro lado, grava na saída padrão.

No meu sistema, recebo a saída um pouco mais descritiva

$ cat ~/.profile | less &
[1] 51758 67354
$
[1] + Done                 cat ~/.profile |
      Stopped (tty output) less

Neste exemplo simples, cat termina de enviar meu .profile para less , mas less não pode exibi-lo, pois é um trabalho em segundo plano. Daí a mensagem Stopped (tty output) less .

O processo less ainda está em execução. É apenas temporário parado. Para alternar para ele, use fg %1 (o número corresponde ao número do trabalho informado entre colchetes na mensagem "parado" e também deve ter sido relatado quando você iniciou o trabalho).

Relacionados: top, top & amp ;, top & comandos no linux

    
por 08.10.2017 / 16:33