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'