Quel est le comportement de `chat | moins

0

J'ai essayé d'exécuter la commande suivante:

cat | less

Je sais que les deux commandes nécessitent quelque chose de l'entrée standard. Quand je le lance, c'est ce à quoi je m'attendais: toutes mes entrées vont à cat et je ne pourrai pas envoyer de commandes à moins (éventuellement sans pouvoir quitter le programme avec la commande q.)

Ce n'est pas ce qui se passe. En fait, cela fonctionne correctement tant que le nombre de lignes envoyées dans l’entrée standard est inférieur au nombre de lignes de l’écran. Lorsque le nombre de lignes envoyées dans l’entrée standard est devenu supérieur au nombre de lignes de ma console, un étrange sentiment s’apparaît. Il semble que l’entrée est parfois envoyée à cat, parfois à less. Par exemple, de manière inattendue, la lettre q parfois laissez le programme quitter.

Pourquoi la raison de ce comportement que je ne m'attendais pas (naïvement)?

user1833218
la source
une autre chose intéressante est si je fais echo a|less il dit 'fin' à la fin, mais pas avec cat | less même quand il frappe moins, avec cat | less, quand il frappe moins, il affiche un signe deux points pour une invite. Ce qui signifie que je suppose qu'il y a plus à l'écran. comme tu dis. Je suppose que la réponse de davidgo à propos de la mise en mémoire tampon pourrait expliquer cela. BTW je remarque juste en tapant less<ENTER> il ne demande pas de stdin, il est donc intéressant que vous puissiez y accéder.
barlop
@barlop nice comment, je suppose que c'est lié à une autre question que j'ai, pourquoi less afilename acceptera les commandes dans l'entrée standard, et cat afilenime|less le fera aussi (l’entrée standard n’est-elle pas less en fait la norme de cat?)
user1833218
moins accepte seulement stdin après avoir reçu stdin. Ainsi, par exemple, tapez cat & lt; ENTER & gt; vous voyez qu'il essaie de lire l'entrée. Mais moins est plus étrange. Essayer moins & lt; ENTER & gt; et il ne lit pas l'entrée. Donnez moins d’entrée, par exemple. un fichier, et ensuite, il veut une entrée. Je ne sais pas trop ce qui se passe avec moins .. Je me demande comment il serait codé, si je le savais alors je l'obtiendrais .. Avez-vous vu un code qui accepte une entrée standard quand il est exécuté? cela vous permet de le diriger et si vous ne le faites pas, il vous le demandera .. je ne sais pas trop si vous devez également spécifier un nom de fichier .. comment cela fonctionne-t-il sur stdin
barlop

Réponses:

2

Le CAT accepte les entrées de stdin (bien qu’il soit discutable de préférer les entrées d’un fichier ou d’un canal), ET LE SORTIE VERS STDOUT

Cela signifie que l'entrée est simplement canalisée à travers chat, puis dirigée vers moins. Ainsi, vous pouvez voir la sortie en moins.

Vos confusions vont probablement se produire avec la mise en mémoire tampon. CAT met l’entrée en mémoire tampon et la mettra en lot (ou attendra la fin du fichier) lors de son envoi vers moins pour le formatage.

davidgo
la source
2

Je me déteste pour dire cela, mais

Il y a plus d’une façon de peler une cat.

J'entends par là entrée standard, puis entrée standard. Ou, il y a la lecture du clavier (terminal), et puis il y a lecture du clavier. Essayer

less < afilename

Ça marche comme

less afilename

ce qui signifie less doit avoir un moyen de lire sur le clavier autre que la lecture de l'entrée standard. Voici une autre commande qui fonctionne, même si vous ne vous y attendiez pas:

less afilename < /dev/null

Regarder la tty commander . Il indique le nom du terminal (terminal) connecté à l’entrée standard. Cela fonctionne en appelant la ttyname fonction de bibliothèque avec un argument de 0 (le descripteur de fichier de l'entrée standard).

less appelle probablement ttyname(1) pour obtenir le nom du terminal (terminal) connecté à la sortie standard. Il ouvre ensuite ce terminal pour la lecture et accepte les commandes de celui-ci. Il ne lit pas les commandes de l'entrée standard. c’est seulement pour les données.

Nous avons donc deux processus quasi indépendants ( cat et less ) indépendamment (simultanément) lecture du clavier (c’est-à-dire le terminal / terminal) sur deux descripteurs de fichiers indépendants. Cette situation est source de confusion et constitue en quelque sorte une «condition de concurrence». Je trouve cela un peu analogue au fonctionnement d’un flipper , dans lequel il y a beaucoup de voies ou chemins que la balle peut prendre - et il faut toujours un ; cela ne peut jamais prendre plus d'un. De même, lorsque plusieurs processus lisent simultanément sur le même terminal, chaque ligne tapée (si le terminal est en mode ligne) ou chaque caractère saisi (si le terminal est en mode caractère) va à exactement un processus. Et la sélection est arbitraire, pas très différente de l'action du flipper. Ce n’est pas complètement «aléatoire», pas plus que la planification des processus est aléatoire; mais c’est essentiellement imprévisible.

Alors, voici ce qui se passe:

  • cat lit à partir de son entrée standard, qui, par défaut, est le terminal, et écrit sur sa sortie standard, qui est le tuyau à less.
  • À un moment donné less appels ttyname(1), obtient le nom du terminal sur lequel il est allumé et l'ouvre pour le lire.
  • less lit un écran plein de données (c'est-à-dire 24 lignes ou autre) de son entrée standard (le tuyau) et l'écrit sur la sortie standard (le terminal).
  • Ensuite, less émet le : invite, met le terminal en mode caractère, et commence à lire du terminal ( ne pas de l'entrée standard).
  • Nous avons donc maintenant deux processus ( cat et less ) lecture simultanée du terminal, et le phénomène du flipper se déclenche - les personnages (et / ou les lignes) que vous tapez allez à cat ou less, semi-aléatoirement. Si ça va à cat, il est écrit dans le tuyau et less traite comme des données. Si ça va à less, il est interprété comme un less commander.

Cela n’a vraiment rien à voir avec la mise en mémoire tampon.

Scott
la source
1
Bonne réponse, mais less vient d'ouvrir /dev/tty: "/ dev / tty: Dans chaque processus, synonyme du terminal de contrôle associé au groupe de processus de ce processus, le cas échéant. Il est utile pour les programmes ou les procédures shell souhaitant être sûr d'écrire des messages ou de lire des données depuis le terminal, quelle que soit la manière dont la sortie a été redirigée. Il peut également être utilisé pour les applications qui demandent le nom d’un fichier pour la sortie, lorsque la sortie typée est souhaitée et qu’il est fastidieux de savoir quel terminal est actuellement utilisé. " (Posix: pubs.opengroup.org/onlinepubs/9699919799/basedefs/… )
rici
D'oh! Tu as raison; J'ai négligé l'évident.
Scott