Que código de escape eu preciso no PS * para garantir que o terminal esteja de volta às configurações normais no prompt do shell?

2

Às vezes eu acidentalmente cat alguns dados binários; algumas vezes algumas falhas do programa ncurses - por várias razões, o terminal pode acabar em mau estado, exigindo o manual reset . Isso está acontecendo com muita frequência.

Esse estado ruim pode não ser echo ou converter tudo para lixo chinês ou muitas outras coisas.

Existe alguma maneira fácil de garantir que as configurações do terminal (sem reinicialização, limpeza de tela, etc.) sejam restauradas quando o shell recuperar o controle?

É bash e Terminal.app , mas eu acho que esse problema é praticamente universal.

    
por taw 06.10.2010 / 06:35

3 respostas

4

Os problemas que você menciona surgem em camadas diferentes e apenas alguns deles podem ser resolvidos com "códigos de escape".

Conjuntos de caracteres alternativos na emulação de terminal

Existe um problema de terminal comum que pode ser descrito como "(algumas) letras minúsculas são exibidas como símbolos ou caracteres de desenho de linhas" (consulte outra pergunta SO ). Isso pode não estar relacionado ao seu problema de “lixo chinês”, mas é a coisa mais próxima que já vi. Você também pode encontrar “lixo chinês” ao interpretar quase qualquer fluxo de dados de 8 bits como texto codificado em UTF-16. Normalmente, esse não é um problema "persistente" que precisa ser redefinido, por isso provavelmente não é o problema que você está vendo.

O problema “preso com os caracteres de desenho de linha” geralmente vem do envio do emulador de terminal a uma sequência de controle não intencional (ou parando um programa antes que ele reinicie o terminal depois de alternar para o conjunto de caracteres alternativos). Isso pode acontecer quando alguns dados binários são exibidos e o fluxo de bytes contém uma seqüência de controle de terminal que seleciona um conjunto de caracteres alternativo.

Isso é fácil de acionar na maioria dos terminais no estilo VT-100, já que bastam apenas um byte (0x0e; consulte minha resposta à questão SO anteriormente vinculada ). A seqüência de controle para redefinir essa condição é também um único byte (0x0f; geralmente produzido via echo ^V^O (digitado como echo Controle + V Controle + O , ou diretamente digitado como printf '7' ).

Você pode esclarecer esse tipo de problema ** fazendo com que seu prompt inclua um byte 0x0f.
** Se o seu "lixo chinês" é devido a algum outro problema, então ele pode ter uma solução diferente.

PS1="\[7\]… "

Os \[ e \] estão lá para dizer bash que o caractere delimitado não é impresso. Isso permite que bash mantenha uma idéia precisa da posição do cursor “físico” (isso é importante para uma nova exibição adequada ao usar a funcionalidade de edição da linha de comando).

Como Ignacio Vazquez-Abrams aponta em sua resposta , outra maneira de obter a seqüência de controle desejada é através do comando tput :

tput rmacs

Usando este método, você pode evitar modificar o PS1 e apenas colocar o comando acima em PROMPT_COMMAND:

PROMPT_COMMAND='tput rmacs'

Opções TTY (termios)

O problema “no echo” *** vem de configurações inesperadas das opções do dispositivo tty baseado em SO que conecta seu emulador de terminal a todos os programas que são executados dentro da janela do terminal. Isso geralmente é causado por programas interativos de interface de usuário de texto que possuem bugs, falhas ou são eliminados para que não sejam capazes de restaurar o tty ao seu estado original.

Você pode controlar essas configurações com o comando stty . Esse tipo de problema não pode ser resolvido com “códigos de escape”, pois as opções do tty são configuradas por meio de APIs de software (consulte tcsetattr (3) e termios (4) ). Geralmente stty sane é um bom mecanismo de reinicialização. *** Também “no ^ C / ^ Z / ^ /”, “saída com degraus escalonados” (nenhum CR automático quando um LF é recebido) e vários outros problemas.

redefinir

O comando reset geralmente pode ajudar com os dois tipos de problemas. Ele enviará sequências de controle de inicialização do terminal que normalmente corrigirão o problema do conjunto de caracteres alternativo e redefinirá as opções do tty para valores razoáveis.

O problema com reset é que ele também imprime mensagens extras em alguns sistemas (por exemplo, “Apagar é…”, “Interromper é…”); você provavelmente não quer que sejam exibidos antes de cada prompt. Se sua implementação de reset envia as mensagens e as seqüências de controle para lugares diferentes (por exemplo, um vai para stdout enquanto o outro vai para stderr), então você pode filtrar as mensagens (por exemplo, PROMPT_COMMAND='reset 2>/dev/null' (veja abaixo) e pule colocando ^ O no prompt).

^ O e stty sane

Em bash , você pode definir o parâmetro PROMPT_COMMAND para o comando e bash será executado se antes de exibir o prompt principal. Você poderia colocar toda a chamada para stty sane lá e colocar ^ O no seu prompt:

PROMPT_COMMAND='stty sane'
PS1="\[7\]… "

Mais uma vez, você pode evitar modificar o PS1 (e manipular terminais no estilo VT-100) usando tput (como sugerido por Ignacio Vazquez-Abrams):

PROMPT_COMMAND='stty sane; tput rmacs'
    
por 06.10.2010 / 08:38
1

Coloque

echo -n "$(tput rmacs)"

em $PROMPT_COMMAND .

    
por 06.10.2010 / 07:30
0

Então eu vou ser menos linha de comando, você sempre tem no xterm ou em qualquer terminal um botão "reset" ou hard reset, para o terminal.app está sob o menu Shell. Envie Hard reset alt-command-r.

    
por 06.10.2010 / 10:30