J'étais juste en train d'exécuter quelques commandes dans un terminal et j'ai commencé à me demander, est-ce qu'Unix / Linux prend des raccourcis lors de l'exécution de commandes piped?
Par exemple, disons que j'ai un fichier avec un million de lignes, dont les 10 premières contiennent hello world
. Si vous exécutez la commande, grep "hello world" file | head
la première commande s'arrête-t-elle dès qu'elle trouve 10 lignes ou continue-t-elle de rechercher d'abord le fichier entier?
command-line
pipe
utilities
efficiency
Chèvre mécontente
la source
la source
-m
argument.Réponses:
Sorte de. Le shell n'a aucune idée de ce que feront les commandes que vous exécutez, il connecte simplement la sortie de l'un à l'entrée de l'autre.
Si
grep
trouve plus de 10 lignes qui disent "bonjour le monde", alorshead
il aura les 10 lignes qu'il veut et fermez le tuyau. Cela entraîneragrep
la mort avec un SIGPIPE, il n'a donc pas besoin de continuer à analyser un fichier très volumineux.la source
grep
continuer à envoyer la sortie dans un vide, similaire à/dev/null
Lorsqu'un programme essaie d'écrire sur un canal et qu'il n'y a pas de lecture de processus à partir de ce canal, le programme d'écriture reçoit un signal SIGPIPE . L'action par défaut lorsqu'un programme reçoit SIGPIPE est de terminer le programme. Un programme peut choisir d'ignorer le signal SIGPIPE, auquel cas l'écriture renvoie une erreur (
EPIPE
).Dans votre exemple, voici une chronologie de ce qui se passe:
grep
ethead
démarrent en parallèle.grep
lit une entrée, commence à la traiter.grep
produit un premier morceau de sortie.head
lit ce premier morceau et l'écrit.grep
pourrait se terminer en premier),head
le nombre de lignes souhaité sera éventuellement imprimé. À ce stade,head
quitte.grep
ethead
, il estgrep
possible que certaines données aient été accumulées et ne les aient pas encore imprimées. Au moment de lahead
sortie,grep
peut lire une entrée ou effectuer un traitement interne, auquel cas il continuera de le faire.grep
, les données seront traitées. À ce stade, il recevra un SIGPIPE et mourra.Il est probable que
grep
cela traitera un peu plus d'entrée que strictement nécessaire, mais généralement seulement quelques kilo-octets:head
lit généralement en morceaux de quelques kilo-octets (car c'est plus efficace que d'émettre unread
appel système pour chaque octet - ce comportement est appelé mise en mémoire tampon), donc le reste du dernier morceau après la dernière ligne souhaitée est rejeté.grep
peut avoir accumulé des données prêtes à devenir un bloc de sortie (mise en mémoire tampon à nouveau). Il recevra SIGPIPE lorsqu'il essaiera de vider son tampon de sortie.Dans l'ensemble, le système est précisément conçu pour que les utilitaires de filtrage se comportent naturellement de manière efficace. Les programmes qui doivent continuer lorsque leur canal de sortie s'éteint doivent prendre la décision d'ignorer le signal SIGPIPE.
la source
Sortof, le pipeline fonctionne comme ceci: il exécute d'abord la première commande puis la deuxième commande dans votre cas.
Autrement dit, soyons
A|B
la commande donnée. Ensuite, il n'est pas certain queA
ouB
commence en premier. Ils peuvent démarrer exactement au même moment s'il y a plusieurs processeurs. Un canal peut contenir une quantité indéfinie mais limitée de données.Si B essaie de lire à partir du canal, mais qu'aucune donnée n'est disponible,
B
attendra que les données arrivent. SiB
lisait à partir d'un disque,B
peut avoir le même problème et doit attendre la fin d'une lecture sur disque. Une analogie plus étroite serait la lecture à partir d'un clavier. Là,B
il faudrait attendre qu'un utilisateur tape. Mais dans tous ces cas, B a commencé une opération de «lecture» et doit attendre sa fin. Mais siB
est une commande telle qu'elle n'a besoin que d'une sortie partielle,A
alors après un certain point où leB
niveau d'entrée est atteintA
, SIGPIPE sera tuéSi
A
essaie d'écrire sur le tuyau et que le tuyau est plein, vousA
devez attendre qu'une certaine place dans le tuyau soit libérée.A
pourrait avoir le même problème s'il écrivait sur un terminal. Un terminal dispose d'un contrôle de flux et peut modérer le rythme des données. Dans tous les cas, toA
, il a démarré une opération "d'écriture" et attendra la fin de l'opération d'écriture.A
etB
se comportent comme des co-processus, bien que tous les co-processus ne communiquent pas avec un tuyau. Aucun des deux n'a le plein contrôle de l'autre.la source
head
quitte), un signal SIGPIPE se produit dans le programme et le comportement par défaut est de quitter.grep
n'a aucun contrôle direct sur le tuyau (il ne fait que recevoir des données), et le tuyau n'a aucun contrôle direct surgrep
(il envoie simplement des données) ...Ce que fait
grep
, ou tout autre programme, dépend entièrement de la logique interne de ce programme. Si vous ditesgrep
via les options de ligne de commande de faire une sortie anticipée une fois trouvé , alors il le fera, sinon il se connectera à la toute fin du fichier à la recherche du modèle ...Le Terminal est également assez déconnecté du fonctionnement interne
grep
etshell
des actions de tuyauterie du ... Le Terminal est fondamentalement juste une rampe de lancement et un affichage de sortie ...la source