Por que (e como) o uso de cat em arquivos binários atrapalhou o terminal?

8

Se eu entendi o catmanual corretamente:

concatenar arquivos e imprimir na saída padrão

catpegará os arquivos como argumento e os imprimirá na saída padrão.
O que eu não entendo é se eu usar o comando:

cat img.png > copy.png

Vou obter 2 arquivos png idênticos, se eu apenas

cat img.png  

Tenho todas as chances de que meu terminal fique bagunçado e interprete mal o que digito.

  • Como isso é possível?
  • Os valores binários ainda são dados binários. Por que simplesmente não mostra uma série de 0 e 1 ou a interpretação desses dados binários em ASCII ou qualquer que seja a codificação no terminal?
  • Esse comportamento também é possível através de catum arquivo de texto contendo caracteres estranhos?
  • Um mecanismo para impedir esse comportamento, como a instrução try {} catch {}, deve ser implementado?
Kiwy
fonte
2
Seu terminal não fica bagunçado. Está em um estado em que você o forçou enviando caracteres de controle. O fato de você não poder mais usá-lo depois de alterar o estado pode não ser o que você queria, mas é inteiramente o resultado de você não entender as consequências de suas ações. Seria o mesmo que mudar a cor da fonte para verde em um processador de texto e dizer que seu processador de texto está bagunçado, apenas porque você não sabe como alterá-lo novamente para a fonte preta sem sair do programa.
Anthon
4
um resetcomando pode ajudar às vezes, mas essa não é uma solução milagrosa.
Ouki
A sequência real a ser digitada é Control-J redefinir Control-J. Quase sempre restaura a sanidade.
Joshua Joshua
1
@ Josué E qual é a diferença entre um pressionamento de tecla solitário resete um resetentre Ctrl-J? Eu não consigo ver nenhuma (nem qualquer razão para seguir o caminho mais complicado)
SyntaxError
1
Como se o terminal foi deixado no modo RAW, Enter gera Ctrl-M em vez de Ctrl-J, para que o shell não veja o pressionamento de tecla necessário para finalizar uma linha e executar o comando.
Joshua

Respostas:

8

cat concatena arquivos fornecidos como argumentos na linha de comando para a saída padrão, lê bytes por vez e, por padrão, não realiza nenhuma interpretação dos bytes que lê.

No seu primeiro exemplo, você está redirecionando o stdout para um arquivo, é por isso que você obtém um novo arquivo.

No seu segundo exemplo, os bytes são gravados no terminal, e é o terminal que interpreta sequências de caracteres como sequências de controle do terminal; é por isso que você obtém um comportamento incomum no terminal. Não tem nada a ver com catisso, catnão sabe o que você fará com a saída. Você pode enviá-lo através de um canal para outro programa para interpretar / processar / imprimir ou tocar "Singing in the rain".

Então, seguindo a filosofia unix,

faça uma coisa, faça apenas uma coisa, mas faça bem

cat não tente adivinhar o que você está tentando fazer.

editar 1 resposta para o primeiro comentário de @ kiwy abaixo.

Sim e não, deixe-me explicar,

Não, se você estiver catem um terminal, porque ele (o software do terminal) está enviando a saída para sua tela ou interpretando as seqüências de controle (emula um hardware antigo, por exemplo, um dispositivo de teletipo ).

mas,

Sim, se você usar um pipe e receber um programa, poderá interpretar os caracteres como comandos.

olhe cat this por exemplo, o cat anyOldShellScript | bashbash irá interpretar o que ele obtém como comandos.

X Tian
fonte
isso significa que se você puder interpretar catum arquivo binário que possa conter instruções em texto sem formatação como rm -rf .esta?
Kiwy
Eu aceito a resposta, mas eu realmente não entendo por que o terminal pode ficar bagunçado assim, se eu digitar como idiota no teclado, nunca consigo obter isso: D
Kiwy
E agora ironia ... hum
kiwy
1
Os caracteres de controle @Kiwy não existem no teclado, mas você pode echoproduzi-los se quiser. Veja stackoverflow.com/questions/5947742/... para saber como fazê-lo e termsys.demon.co.uk/vtansi.htm para alguns do que é possível
David Wilkins
@DavidWilkins hey graças isso é bom, muitas coisas a aprender e há tempo para isso :-(
kiwy
2

Eu acho que isso acontece principalmente por causa de caracteres não imprimíveis com códigos abaixo de 0x20. Esses são códigos especiais de controle / escape, usados ​​para teclas como Backspace, Delete etc.

UVV
fonte