GNU/Linux >> Tutoriels Linux >  >> Linux

Python en mode brut stdin print ajoute des espaces

On dirait que vous ne faites qu'un saut de ligne mais pas de retour chariot. Changez votre impression en

print("ASD", end="\r\n")

Le problème que vous rencontrez est la différence entre les modes 'raw', 'cooked' et 'cbreak'. Et ces modes sont des modes du pilote de terminal au niveau du noyau, pas des modes de votre code d'application ou de la bibliothèque standard ou quoi que ce soit d'autre dans l'espace utilisateur. C'est la façon Unix à l'ancienne de s'y référer. Posix les a remplacés par un ensemble d'attributs beaucoup plus précis, bien que les attributs Posix soient généralement inversés de concert avec les fonctions d'assistance d'une manière qui imite les anciens modes 'raw', 'cooked' et 'cbreak'.

En mode cuit, le pilote de terminal lui-même a une fonctionnalité d'édition de ligne primitive intégrée. Il gère le retour arrière, l'effacement de mots (essentiellement le retour arrière d'un mot entier à la fois) et des choses similaires. Rien de sophistiqué comme la gestion des touches fléchées ou de l'historique ou quelque chose comme ça. Très primitif. Dans ce mode, votre programme ne voit jamais rien du terminal jusqu'à ce que le caractère de fin de ligne (eol) soit envoyé, puis votre programme obtient une ligne entière, et la fin de ligne est traduite au standard Unix \n indépendamment de ce que fait réellement le terminal. De plus, dans le cadre de cela, le pilote de terminal renvoie les caractères saisis au terminal afin que l'utilisateur puisse voir ce qu'il tape.

En mode "cuit", le pilote de terminal au niveau du noyau effectue également une traduction de sortie. Et une partie de cela tourne \n en \r\n si nécessaire.

De plus, en mode "cuit", le pilote de terminal gère les caractères spéciaux comme Control-C (envoie un SIGINT au groupe de processus de contrôle (traduit par CPython en une exception KeyboardInterrupt)) et Control-Z (envoie un SIGTSTP (comme un SIGSTOP, mais peut être capturé) au groupe de processus de contrôle).

En mode 'cbreak', l'édition de ligne n'est plus effectuée. Le pilote de terminal donne immédiatement chaque caractère (ou courte séquence de caractères, comme la séquence d'échappement d'une touche fléchée) au programme. Ces caractères ne sont pas renvoyés à l'écran, et donc à moins que votre programme ne les imprime ensuite, l'utilisateur ne les verra pas. Le pilote de terminal gère toujours les caractères spéciaux comme Control-C et Control-Z, bien qu'il cesse de gérer les caractères d'édition de ligne comme le retour arrière ou le caractère d'effacement de mot (généralement Control-W). De plus, certains traitements de sortie sont toujours effectués, donc le pilote tourne un \n dans un \r\n .

En mode 'raw', aucun traitement n'est effectué sur l'entrée ou la sortie. Pas de gestion de caractères spéciaux, pas d'écho, pas de transformation \n en \r\n , aucune manipulation pour Control-Z, rien. C'est au programme qui met le terminal en mode brut de tout faire.

Maintenant, vous définissez les attributs pour sys.stdin donc vous pouvez penser que cela ne devrait pas affecter sys.stdout . Mais, en fait, vos deux descripteurs de fichier conduisent exactement à la même "instance" d'un pilote de terminal. Et ce sont les paramètres du pilote de terminal qui déterminent ce qui se passe. Peu importe donc si vous modifiez ces paramètres via sys.stdin , sys.stdout , ou même sys.stderr , modifient tous la même instance de pilote de terminal sous-jacent et affectent tous les autres.

Ceci, bien sûr, n'est pas vrai pour les descripteurs de fichiers qui ont été redirigés par le shell avant le lancement de votre programme.

En remarque, vous pouvez utiliser le stty -a sur la ligne de commande pour voir une lecture complète de tous ces drapeaux (y compris quels caractères de contrôle entraînent quels signaux en modes cuit et cbreak).


Google m'a amené ici lorsque je cherchais une réponse à cette même question. L'indice partagé par Halex de l'absence de retour chariot a aidé ma recherche de la vérité. J'ai trouvé mes réponses dans un post sur le Wiki de Chris :https://utcc.utoronto.ca/~cks/space/blog/unix/CBreakAndRaw qui m'a amené à lire la source de tty.py ici :https://hg. python.org/cpython/file/618ea5612e83/Lib/tty.pyCe qui m'a amené à la conclusion que si l'objectif est de lire des caractères uniques, au lieu de :

tty.setraw()

Utiliser :

tty.setcbreak()

Linux
  1. Quels émulateurs de terminaux prennent en charge le mode de contrôle Tmux ?

  2. Commandes de l'éditeur vi[m] du terminal Mac

  3. Le pseudo-terminal ne sera pas alloué car stdin n'est pas un terminal

  4. Comment quitter le terminal Linux en utilisant le script Python ?

  5. Ubuntu 18.04 n'ouvrira pas le terminal après l'installation de Python 3.7.4

Imprimer des fichiers depuis votre terminal Linux

Imprimer les derniers événements spatiaux avec Nextinspace dans le terminal

Linux – Mode clavier brut ?

Est-il possible d'avoir des liaisons de clé Vim dans le terminal ?

Convertir les onglets en espaces dans le terminal Linux avec la commande Expand

comment tracer stdin depuis le terminal?