Sur une machine Centos 6, cela fonctionne:
bash -c 'if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'
et cela ne veut pas:
sh -c 'if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'
Je reçois:
sh: -c: line 0: syntax error near unexpected token `(' sh: -c: line 0: `if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'
Jamais le grep et la queue. Le problème est lié à la substitution de processus: <(...)
Quelqu’un peut-il me dire ce que sh fait différemment ici?
[MODIFIER]
Merci pour les réponses!
Le problème est survenu lors de l’utilisation de capistrano pour les déploiements. Il utilise par défaut sh, mais j’ai changé cela pour le faire maintenant. La raison pour laquelle je ne pouvais pas faire la tuyauterie normale est que lorsque vous utilisez tail -F | grep -q --line-buffered
tail -F | grep -q --line-buffered
, grep ne se terminera pas immédiatement après une correspondance. Il doit y avoir une édition de plus dans le fichier comme echo "" >> catalina.out
et ce n’était pas acceptable dans ma situation.
La syntaxe <(...)
est uniquement prise en charge par BASH.
Pour tout shell POSIX, utilisez cette approche:
sh -c 'tail -n 1000 -F catalina.out | if grep -qP --line-buffered ".+" ; then ...'
c.-à-d. déplacer la redirection stdin devant le if
avec un pipe. Le if
passera stdin sur le grep
.
if tail ...| grep
if tail ...| grep
ne fonctionnera pas car le if
ne pourra pas le voir then
/ fi
car le pipe sépare les processus.
Vous devez noter que la substitution de processus ( <(...)
) n’est pas spécifiée par POSIX. Donc, si vous exécutiez bash
en mode POSIX en l'invoquant avec sh
ou en disant:
set -o posix
alors vous observeriez des erreurs!
A partir du manuel bash :
--posix
Bash avec l'option de ligne de commande--posix
ou si vous exécutez 'set
-o posix
' pendant l'exécution de Bash, Bash se conformera davantage à la norme POSIX en modifiant le comportement pour qu'il corresponde à celui spécifié par POSIX. diffère...
La substitution de processus n'est pas disponible.
Notez également que si Bash est appelé avec le nom sh , il tente de reproduire le comportement de démarrage des versions historiques de sh aussi fidèlement que possible, tout en respectant le standard POSIX.
Si votre sh est en fait un lien vers bash, alors c’est ce qui cause cela.
En cours d’exécution sh --version; sh -c ': <(echo a)'
sh --version; sh -c ': <(echo a)'
devrait vous donner assez d'informations.