Différence de performances entre stdin et l'argument de ligne de commande

11

Pour certaines commandes, il est possible de spécifier certaines entrées comme stdin ou comme argument de ligne de commande.

Plus précisément, supposez que vous commandpouvez prendre l'entrée stdin et un nom de fichier comme argument de ligne de commande, et command < myfile, cat myfile | command et command myfileproduire le même résultat.

Par exemple,

Lorsque la commande est sed:

sed s/day/night/ <myfile >new   
sed s/day/night/ myfile >new    
cat myfile | sed s/day/night/ >new

Lorsque la commande est cat:

cat < myfile
cat myfile
  1. Je me demandais s'il y avait des règles générales sur leurs performances, c'est-à-dire laquelle d'entre elles est généralement la plus efficace et laquelle la moins?
  2. La redirection est-elle toujours meilleure que la pipe?
Tim
la source
1
Je souhaite que tous ceux qui posent ces questions (en double) écrivent leur propre shell à partir de zéro comme exercice.
alex
1
veuillez ne pas utiliser "Merci!" dans vos questions. Votez les réponses pour exprimer votre reconnaissance.
alex
@Alex: S'il s'agit d'un dupe, veuillez créer un lien vers le duplicata et nous travaillerons sur sa fermeture. En règle générale, vous devez vous abstenir de répondre à une question dont vous savez qu'elle est en double et la signaler à l'attention du modérateur.
Caleb
1
@alex: Où puis-je apprendre à écrire mon propre shell?
Tim
@Caleb: Je suis certain que cela a été demandé comme 2 ou 3 fois au cours du mois dernier, mais je n'ai pas le lien à portée de main :-p
alex

Réponses:

6

La cat file | commandsyntaxe est considérée comme une utilisation inutile deCat . De toutes vos options, il faut un impact sur les performances car il doit générer un autre processus dans le noyau. Aussi insignifiant que cela puisse se révéler, il s'agit de frais généraux que les autres formulaires n'ont pas. Cela a été couvert sur des questions telles que: Dois-je me soucier des chats inutiles?

Entre les deux autres formes, il n'y a pratiquement aucune différence de performances. STDIN est un nœud de fichier spécial que le processus doit ouvrir et lire comme n'importe quel autre. Passer un nom de fichier au lieu de STDIN le fait simplement ouvrir un fichier différent.

La différence serait dans les fonctionnalités / flexibilité que vous recherchez.

  • Passer le nom de fichier au programme signifierait que le fichier d'entrée était recherché. Cela peut ou non être important pour le programme, mais certaines opérations peuvent être accélérées si le flux est recherché.
  • La connaissance du fichier d'entrée réel permet à votre programme de potentiellement y écrire. Par exemple sed -ipour l'édition sur place. (Remarque: puisque cela doit créer un nouveau fichier en arrière-plan, ce n'est pas un gain de performances par rapport aux autres redirections, mais c'est une étape de commodité.)
  • L'utilisation de redirections shell vous donne la possibilité de concaténer plusieurs fichiers ou même d'utiliser la redirection de processus. sed [exp] < file1 file2ou même sed [exp] < <(grep command). Les détails de ce cas d'utilisation peuvent être trouvés sur cette question: Substitution de processus et tuyau
Caleb
la source
La substitution de processus devrait fonctionner sans vous obliger à diriger le résultat; sed [exp] < <(grep command)fonctionnera très bien comme sed [exp] <(grep command)(car <(grep command)crée un fichier temporaire nommé pour la longueur de la commande qui sedest parfaitement capable de s'ouvrir de lui-même sans l'aide du shell).
ShadowRanger
2
  1. Étant donné que cela command fileouvre simplement le fichier et fonctionne désormais comme s'il l'était stdin, il n'y a pas de différence. Avec la redirection de shell, vous ouvrez simplement le fichier au préalable (le shell le fait), par opposition à la commande binaire elle-même.

  2. Si nous parlons de cat file | commandvs command <file, alors ce dernier est préféré. Vous ne remarquerez pas de différence de performances significative entre les deux, mais la première est inutilement compliquée (processus supplémentaire et tampon de mémoire partagée pour le canal, avec un débit limité.) De plus, vous ne pouvez pas seek(changer la position du pointeur de fichier arbitrairement) dans un tuyau, tandis que vous pouvez dans un fichier ordinaire. Certaines commandes peuvent utiliser un algorithme plus efficace lorsque seek-ing dans le fichier d'entrée est possible.

alex
la source
Je dirais que le fichier de commandes est préféré à la commande <fichier, car la commande peut effectuer une sorte d'accès non séquentiel.
user606723
Et qu'est-ce qui l'empêcherait de le faire <file? Votre point est valable pour utiliser le nom du fichier d'entrée pour dériver le nom du fichier de sortie difficile, par exemple: gzip fileproduit file.gz.
alex
peut-être que je ne comprends pas comment fonctionne la redirection en interne. Disons que nous redirigeons un film de 12 Go dans mplayer / vlc, puis nous sautons à la fin. Que se passerait-il exactement dans ce cas?
user606723
1
Shell ouvre le fichier et crée un sous-processus, qui hérite du descripteur de fichier. Le processus fourchu closes stdinet appelle duple descripteur de fichier ouvert, donc il remplace l'ancien stdin(qui était une sorte de tty dans la plupart des cas.) Du point de vue du lecteur de film, il n'y a aucune différence entre cela et l'ouverture du fichier par son nom dans le joueur lui-même. Le descripteur de fichier est recherché dans les deux scénarios, donc lorsque nous sautons à la fin, il n'y a pas de différence détectable par l'utilisateur.
alex