Je me demande quand nous devrions utiliser le pipeline et quand nous ne devrions pas.
Dites par exemple, pour tuer certains processus qui gèrent des fichiers pdf, les éléments suivants ne fonctionneront pas en utilisant le pipeline:
ps aux | grep pdf | awk '{print $2}'|kill
Au lieu de cela, nous ne pouvons le faire que de la manière suivante:
kill $(ps aux| grep pdf| awk '{print $2}')
ou
ps aux | grep pdf | awk '{print $2}'| xargs kill
Selon man bash
(version 4.1.2
):
The standard output of command is connected via a pipe to the standard input of command2.
Pour le scénario ci-dessus:
- le stdin de
grep
est le stdout deps
. Ça marche. - le stdin de
awk
est le stdout degrep
. Ça marche. - le stdin de
kill
est le stdout deawk
. Ça ne marche pas.
Le stdin de la commande suivante obtient toujours une entrée du stdout de la commande précédente.
- Pourquoi ça ne marche pas avec
kill
ourm
? - Quelle est la différence entre
kill
,rm
entrée avecgrep
,awk
entrée? - Y a-t-il des règles?
pgrep
,pkill
et leskillall
commandes.pgrep
et le reste peut parfaitement y parvenir :)Réponses:
Il existe deux façons courantes de fournir des contributions aux programmes:
kill
utilise uniquement des arguments de ligne de commande. Il ne lit pas depuis STDIN. Les programmes aimentgrep
etawk
lisent depuis STDIN (si aucun nom de fichier n'est donné comme arguments de ligne de commande) et traitent les données selon leurs arguments de ligne de commande (modèle, instructions, drapeaux, ...).Vous pouvez uniquement diriger vers STDIN d'autres processus, pas vers des arguments de ligne de commande.
La règle courante est que les programmes utilisent STDIN pour traiter une quantité arbitraire de données. Tous les paramètres d'entrée supplémentaires ou, s'il n'y en a généralement que peu, sont passés par des arguments de ligne de commande. Si la ligne de commande peut devenir très longue, par exemple pour de longs
awk
textes de programme, il est souvent possible de les lire à partir de fichiers de programme supplémentaires (-f
option deawk
).Pour utiliser le STDOUT des programmes comme arguments de ligne de commande, utilisez
$(...)
ou en cas de beaucoup de donnéesxargs
.find
peut également cela directement avec-exec ... {} +
.Pour être complet: Pour écrire des arguments de ligne de commande dans STDOUT, utilisez
echo
.la source
gzip
dans le SYNOPSIS, il n'a pas dit qu'il devait prendre un FILENAME en entrée. Je cherche s'il existe un moyen plus systématique de déterminer cela.xargs
vous permettra- t-il pas précisément de "diriger vers des arguments de ligne de commande"?xargs
. Il appelle la commande si nécessaire plusieurs fois (la taille de la ligne de commande est limitée) et propose de nombreuses autres options.C'est une question intéressante, et elle traite d'une partie de la philosophie Unix / Linux.
Alors, quelle est la différence entre les programmes tels que
grep
,sed
,sort
d'une part etkill
,rm
,ls
d'autre part? Je vois deux aspects.L' aspect filtre
Le premier type de programmes est également appelé filtres . Ils prennent une entrée, à partir d'un fichier ou de STDIN, la modifient et génèrent une sortie, principalement vers STDOUT. Ils sont destinés à être utilisés dans un tube avec d'autres programmes comme sources et destinations.
Le deuxième type de programmes agit sur une entrée, mais la sortie qu'ils donnent n'est souvent pas liée à l'entrée.
kill
n'a pas de sortie quand il fonctionne régulièrement, non plusls
. Ils ont juste une valeur de retour pour montrer le succès. Ils ne prennent normalement pas d'entrée de STDIN, mais donnent principalement la sortie de STDOUT.Pour des programmes comme
ls
, l'aspect du filtre ne fonctionne pas si bien. Il peut certainement avoir une entrée (mais n'en a pas besoin), et la sortie est étroitement liée à cette entrée, mais elle ne fonctionne pas comme un filtre. Cependant, pour ce type de programmes, l'autre aspect fonctionne toujours:L' aspect sémantique
Pour les filtres, leur entrée n'a pas de signification sémantique . Ils ne font que lire des données, modifier des données, produire des données. Peu importe qu'il s'agisse d'une liste de valeurs numériques, de noms de fichiers ou de code source HTML. La signification de ces données n'est donnée que par le code que vous fournissez au filtre: l'expression régulière de
grep
, les règles deawk
ou le programme Perl.Pour d'autres programmes, comme
kill
ouls
, leur entrée a un sens , une dénotation .kill
attend les numéros de processus,ls
attend les noms de fichier ou de chemin. Ils ne peuvent pas gérer des données arbitraires et ils ne sont pas censés le faire. Beaucoup d'entre eux n'ont même pas besoin d'entrée ou de paramètres, commeps
. Ils ne lisent pas normalement depuis STDIN.On pourrait probablement combiner ces deux aspects: Un filtre est un programme dont l'entrée n'a pas de signification sémantique pour le programme.
Je suis sûr d'avoir lu quelque part sur cette philosophie, mais je ne me souviens d'aucune source pour le moment, désolé. Si quelqu'un a des sources présentes, n'hésitez pas à les modifier.
la source
Il n'y a pas de "règles" en tant que telles. Certains programmes prennent des entrées de STDIN, et d'autres non. Si un programme peut recevoir des entrées de STDIN, il peut être dirigé vers, sinon, il ne le peut pas.
Vous pouvez normalement dire si un programme prendra ou non une contribution en réfléchissant à ce qu'il fait. Si le travail du programme est de manipuler en quelque sorte le contenu d'un fichier (par exemple
grep
,sed
,awk
etc.), il faut normalement l' entrée STDIN. Si son travail consiste à manipuler le fichier lui - même (par exemplemv
,rm
,cp
) ou d' un processus (par exemplekill
,lsof
) ou à l' information de retour sur quelque chose (par exempletop
,find
,ps
) il ne fonctionne pas.Une autre façon de penser à ce sujet est la différence entre les arguments et les entrées. Par exemple:
Dans la commande ci-dessus,
mv
n'a pas d'entrée en tant que telle. Ce qui lui a été donné, ce sont deux arguments. Il ne sait ni ne se soucie de ce qui se trouve dans aucun des fichiers, il sait juste que ce sont ses arguments et il doit les manipuler.D'autre part
Ici,
sed
a été donné une entrée ainsi qu'un argument. Puisqu'il prend une entrée, il peut la lire depuis STDIN et il peut être redirigé vers.Cela devient plus compliqué lorsqu'un argument peut être l'entrée. Par exemple
Voici
file
l'argument qui a été donnécat
. Pour être précis, le nom du fichierfile
est l'argument. Cependant, comme ilcat
s'agit d'un programme qui manipule le contenu des fichiers, son entrée est tout ce qui se trouve à l'intérieurfile
.Cela peut être illustré à l'aide d'
strace
un programme qui suit les appels système effectués par les processus. Si nous exécutonscat foo
viastrace
, nous pouvons voir que le fichierfoo
est ouvert:La première ligne ci-dessus montre que le programme a
/bin/cat
été appelé et ses arguments étaientcat
etfoo
(le premier argument est toujours le programme lui-même). Plus tard, l'argument afoo
été ouvert en mode lecture seule. Maintenant, comparez cela avecIci aussi,
ls
s'est pris etfoo
comme argument. Cependant, il n'y a pas d'open
appel, l'argument n'est pas traité comme une entrée. Au lieu de cela,ls
appelle lastat
bibliothèque du système (qui n'est pas la même chose que lastat
commande) pour obtenir des informations sur le fichierfoo
.En résumé, si la commande que vous exécutez lira son entrée, vous pouvez y accéder, sinon, vous ne pouvez pas.
la source
kill
etrm
n'ont pas besoin de STDIN.Pour
kill
etrm
, les utilisateurs fournissent leurs informations personnalisées comme argument et$(cmd)
aident à prendre le STDOUTcmd
et à le convertir en argument info.Pour
grep
etawk
, les utilisateurs fournissent des arguments et en plus, égalementSTDIN
ou un fichier normal qui sera traité par la commande.STDIN
peut être passé avec le pipeline|
ou en entrant manuellement.Lisez le manuel ou les codes source. Et si vous ne trouvez rien dont vous avez besoin, vous pouvez faire un test simple mais peut-être dangereux:
Entrez simplement la commande qui vous intéresse, avec des arguments que vous avez déjà compris, et voyez si la commande se met en pause (rien ne se passe). Si elle une pause, il attend réellement pour STDIN (vous pouvez essayer
cat
etecho
de voir les différents). Vous tapez manuellementCtrl-D
et la commande va de l'avant (afficher les résultats ou les erreurs) et retourne. Une telle commande nécessite STDIN dans cette situation (avec les arguments que vous fournissez).La même commande peut ne pas avoir besoin de STDIN dans différentes situations (par exemple,
cat
attend STDIN maiscat file.txt
pas).la source