Aujourd'hui, j'apprends quelque chose sur fifo avec cet article: Introduction aux pipes nommées , qui est mentionné cat <(ls -l)
.
J'ai fait quelques expériences en utilisant sort < (ls -l)
, ce qui fait apparaître une erreur:
-bash: syntax error near unexpected token `('`
Ensuite, j'ai découvert que j'avais mal ajouté un espace supplémentaire dans la commande.
Mais, pourquoi cette commande supplémentaire conduira à cet échec? Pourquoi le symbole de redirection doit-il être proche de (
?
Réponses:
Parce que ce n'est pas un
<
, c'est un<()
qui est complètement différent. C'est ce qu'on appelle la substitution de processus . Il s'agit d'une fonctionnalité de certains shells qui vous permet d'utiliser la sortie d'un processus en tant qu'entrée pour un autre.Les opérateurs
>
et<
redirigent la sortie vers et l’entrée depuis les fichiers . L'<()
opérateur traite des commandes (processus), pas des fichiers. Quand tu coursVous essayez d'exécuter la commande
ls
dans un sous-shell (c'est ce que signifient les parenthèses), puis de transmettre ce sous-shell en tant que fichier d'entréesort
. Ceci, cependant, n'est pas une syntaxe acceptée et vous obtenez l'erreur que vous avez vue.la source
then sort is attempting to read the subshell as its input file
→ c'est évidemment faux, car Bash n'analysera même pas la syntaxe. Ni estls
nisort
est réellement exécuté.< (ls)
n'est pas un jeton valide ici.(ls)
cela fonctionneraitls
dans un sous-shell.Parce que c'est comme ça que ça se passe.
<(...)
inbash
est la syntaxe pour la substitution de processus. Il est copié du même opérateur dansksh
.<
,(
,)
,|
,&
,;
Sont des jetons lexicaux spéciauxbash
qui sont utilisés pour former des opérateurs spéciaux dans différentes combinaisons.<
,<(
,<<
,<&
... ont chacun leur rôle.<
est pour la redirection.<file
,< file
redirigerait l’entrée d’un fichier.<'(file)'
redirige l'entrée d'un fichier appelé(file)
, mais<(file)
est un opérateur différent qui n'est pas un opérateur de redirection.< (file)
serait<
suivi de(file)
. Dans ce contexte, dansbash
,(file)
n'est pas valide.(...)
peut être valide en tant que jeton unique dans certains contextes tels que:Mais pas dans
Dans la
fish
coquille, c'est différent. Infish
,(...)
est utilisé pour la substitution de commande (l'équivalent de$(...)
inbash
). Et<
est destiné à la redirection d’entrée comme dans les shells Bourne-like.Alors dans
fish
:serait la même chose que:
C'est:
Mais c'est quelque chose de complètement différent de
bash
la substitution de processus.Dans le
yash
shell, un autre shell POSIX<(...)
n’est pas destiné à la substitution de processus, mais à la redirection de processus.Là dedans,
Court pour:
est un opérateur de redirection. C'est plus ou moins équivalent à:
Alors que dans
bash
, le<(ls -l)
est étendu au chemin d'un tuyau, il ressemble donc beaucoup à:Dans
zsh
,(...)
est surchargé en tant qu'opérateur de globbing ((*.txt|*.png)
développerait les fichierstxt
et lespng
fichiers) et en tant que qualificateur de globes (*(/)
par exemple, les fichiers de répertoires).Dans
zsh
, dans:Cela
(ls -l)
serait traité comme un qualificatif global. Lel
qualificatif glob est de faire correspondre le nombre de liens et attend un nombre aprèsl
(comme dans lals -ld ./*(l2)
liste des fichiers avec 2 liens), c'est pourquoi vous obtenez unezsh: number expected
erreur.sort < (w)
aurait donné unezsh: no matches found: (w)
erreur à la place car(w)
correspond aux fichiers avec un nom vide qui sont en écriture.sort < (w|cat)
aurait trié le contenu des fichiersw
et / ou ducat
répertoire en cours ...la source
sort < $(ls -l)
donne cette erreur:bash: $(ls -l): ambiguous redirect
$(ls -l)
s'étend à plus d'un mot. Utilisez des guillemets pour empêcher split + glob (sort < "$(echo file)"
). Notez que le comportement oubash
diffère de celui de POSIX sh dans le fait que bash effectue cette division + glob là aussi bien quand il n’est pas interactif (pas quand on l’appelle commesh
si).ls -l | sort /dev/fd/0
je peux dire que la sortie dels -l
est stockée dans/dev/fd/0
et que lasort
commande la lit pour donner la sortie souhaitée. J'utilisetail -f --retry /dev/fd/0
pour surveiller ce fichier mais je n'obtiens aucune sortie. Pourquoi? Comment puis-je lire ce fichier?(foo | psub)
pour obtenir une substitution du processus d’entrée; il n'y a pas encore de substitut (ha) pour la substitution du processus de sortie.