Je veux parcourir la sortie d'une commande sans créer de sous-shell ou utiliser un fichier temporaire.
La version initiale de mon script ressemblait à ceci, mais cela ne fonctionne pas car elle crée un sous-shell, et la exit
commande termine le sous-shell au lieu du script principal qui est requis. Il fait partie d'un script beaucoup plus volumineux pour configurer le routage de stratégie et arrête l'exécution s'il détecte une condition qui entraînera l'échec du routage.
sysctl -a 2>/dev/null | grep '\.rp_filter' | while read -r -a RPSTAT ; do
if [[ "0" != "${RPSTAT[2]}" ]] ; then
echo >&2 "RP Filter must be disabled on all interfaces!"
echo >&2 "The RP filter feature is incompatible with policy routing"
exit 1
fi
done
Une des alternatives suggérées est donc d'utiliser une commande comme celle-ci pour éviter le sous-shell.
while read BLAH ; do echo $BLAH; done </root/regularfile
Il me semble donc que je devrais également pouvoir utiliser une commande comme celle-ci pour éviter le sous-shell et toujours obtenir la sortie du programme que je veux.
while read BLAH ; do echo $BLAH; done <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Malheureusement, l'utilisation de cette commande entraîne cette erreur.
-bash: syntax error near unexpected token `<(sysct ...
Je suis vraiment confus car cela fonctionne.
cat <(sysctl -a 2>/dev/null | grep '\.rp_filter')
Je pouvais enregistrer la sortie de cette commande dans un fichier temporaire et utiliser la redirection sur le fichier temporaire, mais je voulais éviter de le faire.
Alors pourquoi la redirection me donne-t-elle une erreur et ai-je d'autres options que la création d'un fichier temporaire?
la source
Réponses:
Vous avez raté un
<
. Devrait être:Pensez à
<(sysctl -a 2>/dev/null | grep '\.rp_filter')
être un fichier.la source
<(
dans le manuel bash (il se trouve sous «substitution de processus»).Pour quelques autres alternatives si quelqu'un revient ici ...
En fonction du shell, vous pourriez probablement utiliser
set -o errexit
pour que le shell parent se termine lorsqu'une commande (y compris un sous-shell) quitte non nul sans être piégée dans unif
bloc ou un trailing&&
ou||
, comme dansVous pouvez également demander au sous-shell de signaler au parent à l'aide de kill et de la variable d'environnement $ PPID, si disponible.
Ou vous pouvez déplacer le bloc while dans une fonction et retourner 0/1 (renvoyer explicitement 0 après le bloc while) et simplement faire votre pipeline comme
sysctl | grep | function || exit
. Je suppose que vous pouvez également mettre les retours dans le bloc en ligne, mais les fonctions sont votre ami. ;)la source