Votre question est étroitement liée à la façon dont le shell que vous utilisez analyse les entrées utilisateur sur la ligne de commande.
Si le premier mot de la ligne de commande est un programme, situé dans un dossier spécial (principalement défini par PATH
) et qu'aucun autre caractère spécial n'est donné (en fonction du shell que vous utilisez), tous les mots suivants séparés par des espaces ou des tabulations sont passés à le programme sous une forme spéciale, à savoir un tableau. Avec chaque mot comme un élément du tableau.
La façon dont le programme que vous allez invoquer interprète les arguments (situés dans le tableau) dépend de la façon dont il est programmé. Il y a des quasi normes sur la façon dont la syntaxe des arguments devrait ressembler, mais en général le programmeur est entièrement libre. Ainsi, le premier argument peut être interprété comme le nom d'un fichier ou quoi que pense le programmeur au moment où il a écrit le programme.
Dans le cas où vous ajoutez le caractère spécial <
ou >
à votre ligne de commande, le shell ne s'ajoute pas <
et >
ni les mots suivants au tableau qui seront passés au programme. Avec <
ou >
étant donné le shell commence à faire des choses fantaisistes, supporté par le noyau sous-jacent (mot-clé piping ). Pour comprendre ce qui se passe, vous devez comprendre quoi STDIN
et STDOUT
(comme ce n'est pas immédiatement lié, j'ometSTDERR
) sont.
Tout ce que vous voyez sur votre terminal (dans la plupart des cas une partie de votre affichage) est écrit par le shell ou tout autre programme que vous avez appelé précédemment dans un fichier spécial (sous Unix, tout est un fichier ). Ce fichier a un identifiant spécial et est appelé STDOUT
. Si un programme veut lire des données à partir du clavier, il n'interroge pas directement le clavier (au moins dans la plupart des cas) mais lit à partir d'un fichier spécial appelé STDIN
. En interne, ce fichier est connecté à votre périphérique d'entrée standard, votre clavier dans la plupart des cas.
Si le shell lit <
ou >
dans une ligne de commande analysée, il manipule STDIN
ou STDOUT
dans un type particulier pendant la durée d'exécution du programme correspondant. STDIN
et STDOUT
ne pointe plus vers le terminal ou le périphérique d'entrée standard, mais plutôt vers le nom de fichier suivant sur la ligne de commande.
Dans le cas des deux lignes
cat file_name
cat < file_name
le comportement observé est identique car le développeur correspondant fait cat
pour lire STDIN
ou lire les données du fichier, dont le nom est donné comme premier argument de ligne de commande (qui est le premier élément du tableau vers lequel le shell passe cat
). Écrit ensuite cat
tout le contenu de file_name
ou STDIN
vers le terminal car nous n'instruisons pas le shell à manipuler STDOUT
. N'oubliez pas que dans la deuxième ligne, votre shell manipule STDIN
de cette manière, qu'il ne pointe plus vers votre périphérique d'entrée standard mais pointe vers un fichier appelé file_name
dans votre répertoire de travail actuel.
Dans l'autre cas de la ligne
man < file_name
man
n'est pas censé lire quoi STDIN
que ce soit s'il est appelé sans argument, c'est-à-dire un tableau vide. Donc la ligne
man < file_name
équivaut à
man
Par exemple man
, lira quelque chose STDIN
, aussi si vous passez -l -
à man
. Avec cette option donnée sur la ligne de commande, vous pouvez afficher le contenu de tout ce qui se man
lit STDIN
sur votre terminal. Donc
man -l - < file_name
fonctionnerait également (mais attention, ce man
n'est pas seulement un pager, mais il analyse également l'entrée du fichier et le contenu du fichier et le contenu affiché peuvent différer).
Alors, comment STDIN
, STDOUT
et les arguments de ligne de commande sont interprétés dépend du développeur correspondant.
J'espère que ma réponse éclaircira les choses.
man -l - < file_name
pour faire desman
interprètesSTDIN
comme arguments, mais cela échoue dans mon système avecSTDERR
:man -l - < tee man: invalid option -- l man, version 1.6c
man
( man-db ) lit les argumentsSTDIN
avec les arguments donnés-l
suivis de-
. Il interprète simplement les données à partirSTDIN
d'une page de manuel. Pour des explications plus détaillées des arguments valides et de la façon dont ils sont interprétés, vous devez consulter la page de manuel du programme associé. Dans votre cas, consultezman man
. Il existe peut-être une option similaire pour votreman
. Si vous souhaitez lire les arguments de ligne de commande pour un programme spécifique à partir deSTDIN
xargs
(comme mentionné ci-dessus), c'est la voie à suivre.man man
trouve que celui de mon système d'exploitation ne le prend pas en charge. Quoi qu'il en soit, merci pour cette déclaration de ces deux concepts pour moi.Ils sont complètement différents. Les arguments de ligne de commande sont passés au programme dans un tableau et il peut faire ce qu'il veut avec eux; stdin est un flux d'entrée auquel le programme doit demander des données. Les programmes qui traitent les fichiers choisissent souvent de prendre en charge les deux, mais ils doivent le faire manuellement - ils vérifient si un nom de fichier a été passé comme argument de ligne de commande, et sinon ils lisent à partir de stdin à la place
Vous semblez vous attendre
man
à lire stdin pour trouver la page de manuel qu'il doit afficher, ce qui serait un comportement vraiment étrange; quand utiliseriez-vous cela? Le fait d'cat
afficher son stdin est un artefact du fait qu'il ne fait rien d'autre; Je ne pense pas qu'un autre outil fonctionne de cette façon. Par exemple,grep
peut prendre un nom de fichier ou lirestdin
, mais il traite les donnéesstdin
, il ne lit pas un nom de fichierstdin
et l'ouvreSi vous avez vraiment besoin de ce comportement, vous pouvez utiliser
xargs
ce qui convertit un fichier en arguments de ligne de commande:Ou tout simplement intégrer un
cat
appel dans l'man
appel:la source
man $(<file_name)
.(<>)
dans une boucle feraSTDIN
ou des arguments en ligne de commande comme noms de fichiers ...man < file_name
est de m'aider à comprendre ces deux concepts. À la lecture de votre explication, la mise en œuvre est décidée par l'auteur de la commande. Donc, si je sous droite, lesfind
arguments prend plutôt les processus STDIN?