Quelle est la difference entre <<
, <<<
et < <
in bash?
command-line
bash
redirect
Searene
la source
la source
Réponses:
Ici le document
<<
est connu commehere-document
structure. Vous laissez le programme savoir quel sera le texte de fin et, chaque fois que ce séparateur sera vu, le programme lira tout ce que vous lui avez donné en entrée et effectuera une tâche.Voici ce que je veux dire:
Dans cet exemple, nous indiquons au
wc
programme d'attendre uneEOF
chaîne, puis nous tapons cinq mots, puisEOF
nous signalons que nous avons terminé la saisie. En fait, cela ressemble à courir toutwc
seul, taper des mots, puis appuyer surCtrlDEn bash, ceux-ci sont implémentés via des fichiers temporaires, généralement sous la forme
/tmp/sh-thd.<random string>
, alors qu'en tirets, ils sont implémentés sous forme de canaux anonymes. Cela peut être observé via le suivi des appels système avecstrace
commande. Remplacezbash
parsh
pour voir comment/bin/sh
effectue cette redirection.Ici la chaîne
<<<
est connu commehere-string
. Au lieu de taper du texte, vous donnez une chaîne de texte prédéfinie à un programme. Par exemple, avec un tel programme quebc
nous pouvons fairebc <<< 5*4
pour obtenir simplement une sortie pour ce cas spécifique, il n’est pas nécessaire d’exécuter bc de manière interactive.Ici, les chaînes de bash sont implémentées via des fichiers temporaires, généralement au format
/tmp/sh-thd.<random string>
, qui sont ensuite dissociés, leur permettant ainsi d’occuper temporairement de l’espace mémoire, mais ne figurant pas dans la liste des/tmp
entrées de répertoires, et existant en tant que fichiers anonymes, qui peuvent encore être référencé via le descripteur de fichier par le shell lui-même, et ce descripteur de fichier étant hérité par la commande puis dupliqué sur le descripteur de fichier 0 (stdin) via unedup2()
fonction. Ceci peut être observé viaEt via le suivi des appels système (sortie abrégée pour des raisons de lisibilité; notez comment le fichier temporaire est ouvert en tant que fd 3, les données qui y sont écrites, puis il est rouvert avec
O_RDONLY
flag en tant que fd 4 et plus tard sans lien, puisdup2()
sur fd 0, qui est hérité par lacat
suite ):Opinion: potentiellement parce que les chaînes utilisent des fichiers texte temporaires, c’est peut-être la raison pour laquelle les chaînes insèrent toujours une nouvelle ligne de fin, puisqu'un fichier texte défini par POSIX doit comporter des lignes qui se terminent par un caractère de nouvelle ligne.
Processus de substitution
Comme l' explique tldp.org ,
Donc, en pratique, cela ressemble à la tuyauterie stdout d’une commande à l’autre, par exemple
echo foobar barfoo | wc
. Mais remarquez: dans la page de manuel bash, vous verrez qu’elle est notée comme<(list)
. Donc, fondamentalement, vous pouvez rediriger la sortie de plusieurs (!) Commandes.Remarque: techniquement, lorsque vous dites que
< <
vous ne faites pas référence à une chose, mais à deux redirection avec une redirection unique<
et en mode processus de la sortie<( . . .)
.Maintenant que se passe-t-il si nous ne faisons que traiter la substitution?
Comme vous pouvez le constater, le shell crée un descripteur de fichier temporaire dans
/dev/fd/63
lequel le résultat est envoyé (ce qui, selon la réponse de Gilles , est un canal anonyme). Cela signifie<
que ce descripteur de fichier redirige comme entrée dans une commande.Un exemple très simple consisterait à effectuer une substitution de processus de la sortie de deux commandes echo dans wc:
Donc, ici, nous faisons en sorte que le shell crée un descripteur de fichier pour toutes les sorties qui se produisent dans la parenthèse et redirige celui-ci en entrée vers
wc
. Comme prévu, wc reçoit ce flux de deux commandes echo, qui à elles seules produiraient deux lignes, chacune ayant un mot, et de manière appropriée, nous avons 2 mots, 2 lignes et 6 caractères plus deux nouvelles lignes comptées.Side Note: La substitution de processus peut être considéré comme un bash (une commande ou une structure utilisable dans des coquilles avancées telles que
bash
, mais non spécifiée par POSIX), mais il a été mis en œuvre dansksh
l'existence de bash avant que la page man ksh et cette réponse suggère. Les coquilles aimenttcsh
etmksh
n'ont cependant pas de processus de substitution. Alors, comment pourrions-nous rediriger la sortie de plusieurs commandes dans une autre commande sans substitution de processus? Regroupement plus tuyauterie!Effectivement, c'est la même chose que l'exemple ci-dessus. Cependant, cela est différent du remplacement de processus, puisque nous faisons stdout de tout le sous-shell et stdin de
wc
lié au tuyau . D'autre part, la substitution de processus fait en sorte qu'une commande lise un descripteur de fichier temporaire.Donc, si nous pouvons faire un regroupement avec une tuyauterie, pourquoi avons-nous besoin d'une substitution de processus? Parce que parfois nous ne pouvons pas utiliser de tuyauterie. Prenons l'exemple ci-dessous - comparaison des résultats de deux commandes avec
diff
(ce qui nécessite deux fichiers, et dans ce cas, nous lui donnons deux descripteurs de fichier)la source
< <
est utilisé quand on obtient stdin d'une substitution de processus . Une telle commande pourrait ressembler à :cmd1 < <(cmd2)
. Par exemple,wc < <(date)
< <
ce n'est pas une chose en soi, dans le cas d'une substitution de processus, c'est juste un<
suivi par quelque chose d'autre qui commence par l'utilisateur<
<<<
a d'abord été implémenté par le port Unix de Plan 9 shell rc, puis adopté plus tard par zsh, bash et ksh93. Je n'appellerais pas cela un bashisme.echo 'foo' | read; echo ${REPLY}
ne pas revenirfoo
, carread
on a commencé dans un sous-shell - la tuyauterie commence un sous-shell. Cependant,read < <(echo 'foo'); echo ${REPLY}
renvoie correctementfoo
, car il n'y a pas de sous-shell.< <
est une erreur de syntaxe:< <()
Le processus substitution (<()
) est-il combiné à la redirection (<
):Un exemple artificiel:
Avec la substitution de processus, le chemin d'accès au descripteur de fichier est utilisé comme un nom de fichier. Si vous ne voulez pas (ou ne pouvez pas) utiliser directement un nom de fichier, vous combinez la substitution de processus avec la redirection.
Pour être clair, il n'y a pas d'
< <
opérateur.la source
<()
à un nom de fichier, il est donc généralement utile: il< <()
remplace le stdin s'il n'est pas nécessaire. Danswc
, ce dernier se trouve être plus utile. Cela pourrait être moins utile ailleurs< <
est une erreur de syntaxe, vous voulez probablement direcommand1 < <( command2 )
qui est une simple redirection d’entrée suivie d’un processus de substitution et qui est très similaire mais n’équivaut pas à:La différence en supposant que vous exécutez
bash
estcommand1
exécutée dans un sous-shell dans le deuxième cas, alors qu'elle est exécutée dans le shell actuel dans le premier. Cela signifie que les variables définiescommand1
ne seront pas perdues avec la variante de substitution de processus.la source
< <
donnera une erreur de syntaxe. L'utilisation appropriée est la suivante:Expliquer à l'aide d'exemples:
Exemple pour
< <()
:Dans l'exemple ci-dessus, l'entrée dans la boucle while proviendra de la
ls
commande qui peut être lue ligne par ligne etecho
ed dans la boucle.<()
est utilisé pour la substitution de processus. Vous trouverez plus d’informations et d’exemples<()
sur ce lien:Processus de substitution et pipe
la source