Prompt do Bash abaixo da saída - cauda do log em segundo plano

15

Eu trabalhava para uma empresa que possuía um shell personalizado para gerenciamento de um de seus produtos em execução no Linux e pretendo replicar um recurso essencial desse shell.

Todo o trabalho foi realizado por um processo em segundo plano e a saída do log exibida para todos os usuários conectados.

O log seria direcionado em segundo plano para o seu shell, e a linha de prompt sempre permaneceria perfeitamente na parte inferior.

Por exemplo

Log line 1
Log line 2
Log line 3
![ROOT@PRODUCT51-LIVE]:~/ #

A maneira como tentei fazer isso com o bash era iniciar uma cauda desanexada no arquivo .bashrc dos usuários, mas quando a saída do comando é enviada para o stdout - ela aparece no prompt do bash, por exemplo

![ROOT@PRODUCT51-LIVE]:~/ #Log line 1
Log line 2
Log line 3

E o usuário teria que pressionar enter ou CtrlCpara obter uma linha de prompt limpa.

Estou sem ideias de como fazer com que o prompt sempre pule para o final da saída e acho que estou usando a terminologia errada para encontrar qualquer coisa no Google, pois não estou tendo sorte - alguém sabe como fazer isso com festança?

iamacarpet
fonte
1
Você deseja que a saída seja atualizada instantaneamente ou quando receber um novo prompt?
ahilsend
Instantaneamente, é o mais idêntico possível ao executar "tail -f", mas com o prompt na parte inferior.
Iamacarpet
O que acontece com a tail -fsaída e o prompt e a saída do comando quando você insere um comando com uma quantidade significativa de saída, especialmente quando o processo em segundo plano está enviando ativamente sua saída?
Pausado até novo aviso.
No caso deles, os comandos que seriam executados causavam apenas a saída pelo processo em segundo plano, não por conta própria, portanto não era um problema. Nesse caso, uma vez que tenhamos uma solução que dê o efeito desejado, acho que seria um caso de jogar e ver o quão ruim a saída seria misturada em uma implementação de implementação.
Iamacarpet
1
Então eu apoio fortemente a sugestão de usar o screen ou tmux. A saída não será misturada ou lutará pelo espaço na tela e você pode redimensionar as janelas (mover a divisão) e rolar elas independentemente. Se sua objeção é que as linhas de cabeçalho / rodapé / status sejam "pesadas", existe alguma capacidade de configurar isso. Nenhuma roda reinventada.
Pausado até novo aviso.

Respostas:

1

A seguir, você faz o que precisa, sem usar o tmux, o screen ou outros programas. Mantém o prompt na parte inferior. Substitua "/ var / log / cron" pelo arquivo que você precisar:

#!/bin/bash 
L=$(tput lines)
L1=${L}
(( L1-- ))
C=$(tput cols)
tput cup ${L} 0
tail -f /var/log/cron | while read line; do 
  tput sc
  printf "\e[1;${L1}r\e[${L1};${C}f" 
  echo; echo ${line}
  printf "\e[1;${L}r" && tput rc
done

a chave para isso são os caracteres de controle ANSI do terminal. Particularmente a instrução "\ e [x; y" que define uma nova área rolável. Portanto, à medida que cada linha do arquivo de log é lida, a linha inferior da janela é excluída da área de rolagem, a linha do arquivo de log é inserida e a parte inferior é adicionada novamente.

Michael Martinez
fonte
Obrigado Michael, que funciona lindamente =] - Eu tenho o problema ocasional de que você está digitando enquanto há muita linha de registro rolando, você não pode retroceder todo o texto na linha do console (eu estava testando com um log apache ocupado), mas para o que eu quero usá-lo, não deve ser um problema.
Iamacarpet
@iamacarpet Awesome. Que bom que funciona para você.
Michael Martinez
11

A resposta é tela ou tmux está sendo usado

Vou explicar como você pode configurar esse usando a tela

1) Instale a tela usando derivados do apt-get install screenUbuntu / Debian ou yum install screenRedHat.

2) screen -S shell_and_logs

3) Pressione Ctrl+ a, seguido de S(capital S).
Uma tela horizontal aparecerá

4) Pressione Ctrl+ aseguido de TAB
Isto pulará para a segunda janela dividida.

5) Crie outra janela aqui para obter o prompt de comando pressionando Ctrl+ asolte as teclas e pressionec

6) Você pode redimensionar o segundo windo pressionando Ctrl+ ae digitando :resizeapós o que Lines:será exibido. Digite o número de linhas que você deseja mostrar.

7) Finalmente, você pode alternar entre janelas por Ctrl+ aseguido porTAB

Veja o exemplo abaixo

Valentin Bajrami
fonte
Obrigado val0x00ff - eu gosto da idéia, ele faz o trabalho - mas não parece tão limpo quanto a experiência fornecida pelo sistema em questão. Para um usuário inexperiente, não é tão transparente - é obviamente outro shell, em vez de apenas sentir que seu shell principal o mantém atualizado.
Iamacarpet
@iamacarpet Essa tail -F /var/log/messages &é outra maneira de mostrar mensagens quando algo muda, por exemplo, quando uma falha de login é descoberta ou quando algum serviço tem problemas. No entanto, isso não é o ideal, pois irá danificar seu shell interativo.
Valentin Bajrami
Sim, era exatamente isso que eu estava perguntando - uma maneira de fazer exatamente isso sem bagunçar o shell interativo - como foi o que eles conseguiram fazer no shell da empresa - mas seria bom não precisar escrever um shell do zero para conseguir isso.
Iamacarpet
1
@iamacarpet Há um monte de outras ferramentas além screene tmuxque pode fazer isso -, por exemplo, alguns dos BSDs fornecido com um windowcomando. Dada a opção, porém, eu recomendaria esta solução em um shell personalizado ou em outras opções disponíveis devido à sua flexibilidade. Pode não ser tão transparente para o usuário final, mas eles realmente não sabem a diferença e os usuários avançados / administradores de sistemas poderão usar a flexibilidade extra oferecida por screen.
precisa saber é o seguinte
@iamacarpet t=$(mktemp); printf '%s\n' 'screen tail -F /var/log/messages' split focus screen > "$t"; screen -S screenname -c "$t"Coloque-o em um script e execute-o sempre que desejar. Graças à geirha para este em #bash @ irc.freenode.org
Valentin Bajrami