Pourquoi (et comment) l'utilisation de cat sur des fichiers binaires a-t-elle gâché le terminal?

8

Si je comprends bien le catmanuel:

concaténer des fichiers et imprimer sur la sortie standard

catprendra les fichiers en argument et les imprimera sur la sortie standard.
Ce que je n'obtiens pas, c'est si j'utilise la commande:

cat img.png > copy.png

J'obtiendrai 2 fichiers png identiques alors que si je viens

cat img.png  

J'ai toutes les chances que mon terminal soit foiré et mal interprété ce que je tape.

  • Comment est-ce possible?
  • Les valeurs binaires sont toujours des données binaires. Pourquoi ne montre-t-il pas simplement une série de 0 et 1 ou l'interprétation de ces données binaires en ASCII ou quel que soit l'encodage dans le terminal?
  • Ce comportement est-il également possible en catcréant un fichier texte contenant des caractères étranges?
  • Un mécanisme pour empêcher ce comportement comme l'instruction try {} catch {} doit-il être implémenté?
Kiwy
la source
2
Votre terminal ne se gâche pas. Il est dans un état dans lequel vous l'avez forcé en lui envoyant des caractères de contrôle. Le fait que vous ne puissiez plus l'utiliser après avoir changé d'état n'est peut-être pas ce que vous vouliez, mais c'est entièrement dû au fait que vous ne comprenez pas les conséquences de vos actions. Ce serait la même chose que de changer la couleur de votre police en vert dans un traitement de texte et de dire que votre traitement de texte est foiré, uniquement parce que vous ne savez pas comment le rétablir en police noire sans par exemple quitter le programme.
Anthon
4
une resetcommande peut parfois aider, mais ce n'est pas une solution miracle.
Ouki
La séquence réelle à taper est Control-J reset Control-J. Restaure presque toujours la raison.
Joshua
1
@Joshua Et quelle est la différence entre une touche solitaire resetet une resettouche Ctrl-J? Je ne vois aucune (ni aucune raison d'aller de la manière la plus compliquée)
erreur de syntaxe
1
Parce que si le terminal était laissé en mode RAW, Enter génère Ctrl-M au lieu de Ctrl-J afin que le shell ne voit pas la frappe nécessaire pour terminer une ligne et exécuter la commande.
Joshua

Réponses:

8

cat concatène les fichiers fournis comme arguments sur la ligne de commande à la sortie standard, il lit les octets à la fois et, par défaut, n'effectue aucune interprétation des octets qu'il lit.

Dans votre premier exemple, vous redirigez stdout vers un fichier, c'est pourquoi vous obtenez un nouveau fichier.

Dans votre deuxième exemple, les octets sont écrits sur le terminal, et c'est le terminal qui interprète les séquences de caractères comme des séquences de contrôle pour le terminal, c'est pourquoi vous obtenez un comportement inhabituel sur votre terminal. Cela n'a rien à voir avec catcela, catje ne sais pas ce que vous allez faire avec sa sortie. Vous pouvez l'envoyer via une pipe vers un autre programme pour interpréter / traiter / imprimer ou jouer "Chanter sous la pluie".

Donc, suivant la philosophie unix,

faire une chose, faire une seule chose, mais bien le faire

cat ne devrait pas essayer de deviner ce que vous essayez de faire.

modifier 1 réponse au 1er commentaire de @ kiwy ci-dessous.

Oui et non, laissez-moi vous expliquer,

Non, si vous vous connectez catà un terminal, car il (le logiciel du terminal) envoie la sortie à votre écran ou interprète des séquences de contrôle (il émule un ancien matériel, c'est-à-dire un périphérique téléscripteur ).

mais,

Oui, si vous vous adressez à un tuyau et que le programme reçu peut interpréter les caractères comme des commandes.

regardez cat this pour un exemple, cat anyOldShellScript | bashbash interprétera ce qu'il obtient comme des commandes.

X Tian
la source
cela signifie-t-il que si vous catun fichier binaire qui peut contenir des instructions en texte brut comme rm -rf .celui-ci pourrait être interprété?
Kiwy
J'accepte la réponse bien que je ne comprenne pas vraiment pourquoi le terminal peut être gâché comme ça si je tape comme un abruti sur mon clavier, je n'arrive jamais à obtenir ceci: D
Kiwy
Et maintenant, ironie ... hum
Kiwy
1
Les caractères de contrôle @Kiwy n'existent pas sur votre clavier, mais vous pouvez les faire echosortir si vous le souhaitez. Voir stackoverflow.com/questions/5947742/… pour savoir comment le faire et termsys.demon.co.uk/vtansi.htm pour une partie de ce qui est possible
David Wilkins
@DavidWilkins hey merci c'est sympa, tellement de choses à apprendre et pas de temps pour ça :-(
Kiwy
2

Je suppose que cela se produit principalement en raison de caractères non imprimables avec des codes inférieurs à 0x20. Ce sont des codes de contrôle / d'échappement spéciaux, qui sont utilisés pour des touches comme Retour arrière, Supprimer, etc.

UVV
la source