Quand dois-je utiliser la redirection d'entrée?


21

J'ai utilisé les deux commandes suivantes pour produire les mêmes résultats: -

[root@localhost ~]# grep line comments
The line should start with a single quote to comment in VB scripting.
Double slashes in the beginning of the line for single line comment in C.
[root@localhost ~]#

[root@localhost ~]# grep line <comments
The line should start with a single quote to comment in VB scripting.
Double slashes in the beginning of the line for single line comment in C.
[root@localhost ~]#

Pourriez-vous s'il vous plaît m'expliquer les avantages / inconvénients si l'une de ces 2 approches l'une sur l'autre.

Réponses:


28

Depuis la man greppage (sur Debian):

LA DESCRIPTION

   grep  searches the named input FILEs (or standard input if no files are
   named, or if a single hyphen-minus (-) is given as file name) for lines
   containing  a  match to the given PATTERN.  By default, grep prints the
   matching lines.

Dans le premier cas, grepouvre le fichier; dans le second, le shell ouvre le fichier et l'affecte à l'entrée standard de grep, et grepsans qu'aucun argument de nom de fichier ne soit transmis, il suppose qu'il doit grep son entrée standard.

Avantages de 1:

  • grep peut grep plus d'un fichier¹.
  • greppeut afficher le nom du fichier où se trouve chaque occurrence de line.

Avantages de 2:

  • Si le fichier ne peut pas être ouvert, le shell renvoie une erreur qui inclura des informations plus pertinentes (comme le numéro de ligne dans le script) et de manière plus cohérente (si vous laissez le shell ouvrir des fichiers pour d'autres commandes également) que lorsque grepl'ouvre. Et si le fichier ne peut pas être ouvert, il grepn'est même pas appelé (ce qui pour certaines commandes - peut-être pas grep- peut faire une grande différence).
  • dans grep line < in > out , si inne peut pas être ouvert, outne sera pas créé ou tronqué.
  • Il n'y a aucun problème avec certains fichiers avec des noms inhabituels (comme - ou des noms de fichiers commençant par -) ².
  • cosmétique: vous pouvez mettre <file n'importe où sur la ligne de commande pour afficher le flux de commandes plus naturellement, comme <in grep line >outsi vous préférez.
  • cosmétique: avec GNU grep, vous pouvez choisir quelle étiquette utiliser devant la ligne correspondante au lieu du nom du fichier comme dans:

    <file grep --label='Found in file at line' -Hn line
    

En termes de performances, si le fichier ne peut pas être ouvert, vous enregistrez l'exécution de grep lors de l'utilisation de la redirection, mais sinon, grepje ne m'attends pas à beaucoup de différence.

Avec la redirection, vous évitez de devoir passer un argument supplémentaire à grep , vous grepsimplifiez légèrement l'analyse des arguments. D'autre part, le shell aura besoin (au moins) d'un appel système supplémentaire au dup2()descripteur de fichier sur le descripteur de fichier 0.

Dans { grep -m1 line; next command; } < file, grep(ici GNU grep) voudra seek()revenir juste après la ligne correspondante pour next commandvoir le reste du fichier (il devra également déterminer si le fichier est recherché ou non). En d'autres termes, la position dans stdin est une autre grepsortie de. Avec grep -m1 line file, il peut optimiser cela, c'est une chose de moins pourgrep à prendre en compte.


Remarques

¹ Avec zsh, vous pouvez faire:

grep line < file1 < file2

mais cela fait l'équivalent de cat file1 file2 | grep line(sans invoquer lecat utilitaire) et est donc moins efficace, peut causer de la confusion si le premier fichier ne se termine pas par un caractère de nouvelle ligne et ne vous permettra pas de savoir dans quel fichier le modèle est trouvé.

² Dans le cas de ksh93et bashcependant, il y a des fichiers comme /dev/tcp/host/port(et /dev/fd/xsur certains systèmes en bash) qui, lorsqu'ils sont utilisés dans la cible des redirections, le shell intercepte à des fins spéciales au lieu d'ouvrir vraiment le fichier sur le système de fichiers (bien qu'en général, ces fichiers n'existent pas sur le système de fichiers). /dev/stdinsert le même objectif que celui -reconnu par grep, mais au moins, ici, il est plus correctement espacé (tout le monde peut créer un fichier appelé -dans n'importe quel répertoire, tandis que seuls les administrateurs peuvent créer un fichier appelé /dev/tcp/host/portet les administrateurs devraient mieux savoir).


+1, pour la belle explication. J'ai un doute: dans le 2ème cas, lorsque le shell ouvre le fichier, passe-t-il le contenu du fichier ouvert à l'entrée standard (clavier) ?? (Je me suis confondu avec le terme «entrée standard de grep»).
Ankit

1
@Ankit, stdin est l'endroit où les applications lisent leur entrée par défaut, le descripteur de fichier 0. Dans un terminal, fd 0 est ouvert à partir de la lecture sur le terminal (quelque chose comme / dev / ttyxx ou / dev / pts / n). Voilà comment ils finissent par obtenir ce que vous tapez sur le clavier. La redirection shell du stdin d'une commande ouvre simplement le fd 0 vers un autre fichier avant d'exécuter la commande.
Stéphane Chazelas

6

La réponse de StephaneChazelas couvre grep(1), et la plupart des commandes de lignée Unix fonctionnent de cette façon, mais pas toutes. Il est standard de lire soit à partir d'une entrée standard (à partir du clavier, d'un fichier redirigé via < fileou de la sortie canalisée par une autre commande, exemple stupide ls * | grep '^ab*c$'), soit à partir du ou des fichiers donnés comme arguments, comme grep comment file1 file2 file3. Certaines commandes utilisent la convention selon laquelle le fichier nommé -est une entrée standard, vous pouvez donc dire make-middle | cat head - taild'obtenir un flux avec head, quoi qu'il gen-middlegénère, suivi de tail. C'est par conception, pour donner de la flexibilité dans l'utilisation des commandes.

Ce qui est mieux? Tant qu'il fonctionne, cmd fileest plus court que cmd < file; il pourrait y avoir une petite différence de temps entre le shell faisant le fichier frobbing ( <) et la commande le faisant lui-même, mais probablement imperceptible à moins que vous ne fassiez rien d'autre toute la journée. Cela dépendra de considérations telles que les avantages mentionnés dans la réponse de Stéphane.


cmd filen'est pas plus court que cmd<filesi.
Stéphane Chazelas

Cependant, c'est une frappe plus courte, en supposant que vous devez appuyer sur Maj pour taper a <.
DopeGhoti
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.