Comment Imbriquer && (AND) et || ( OR ) en bash ?

Bonjour,
Avec le code suivant,

mount | egrep '/mnt/S_racine/lv_var' && echo 'Déja montée' ||\
    sudo mount -t xfs /dev/mapper/groupe_unique-lv_var /mnt/S_racine/lv_var &&\
    echo " montée " || exit 5

J’espérai avoir le comportement suivant:
1 savoir si la partition est bien monté ( c’est OK )
2 si c’est le cas afficher ‘Déja monté’ ( c’est OK )
sinon la monter ( c’est OK )
et alors seulement afficher ‘montée’ ( et la ça affiche même si c’était déjà monté )
3 Enfin sortir du script si ce montage a échoué ( erreur pas encore testée, mais sans problème: ça ne sort pas )

On voit que le “&&” après un “||” garde la vérité de la 1ère commande si le “||” est faux (donc inutile)
J’aimerai donc regrouper les conditions, un peu comme ceci:

commande1 && echo OK || ( commande2 && echo OK || ( echo message ; exit ) )

Malheureusement, je crois que le regroupement des commandes entre parenthèses lance un sous-shell , et dans ce cas “exit” ne fait que sortir du sous-shell.[size=85]( et même, ici du 2e sous-shell )[/size]

La question: existe-t-il un moyen de faire des regoupements de commandes dans la même instance (le même processus) du shell ?

Merci à tous

Réponse: ?
remplacer les parenthèses de mon exemple par des accolades { } ( comme en Perl )

mount | egrep '/mnt/S_racine/S_boot' && echo 'Déja montée' ||\ ( sudo mount -t ext4 -U 743abb88-2fe8-4dbe-891c-adcc16708a52 /mnt/S_racine/S_boot &&\ echo " montée ") || { echo '/mnt/S_racine/S_boot N'A PAS PU ÊTRE MONTÉ ; exit 2 }
ne marche pas:
La commande n’est pas finie:
en ligne de commande, on obtient une invite (un prompt):

et en script, un message "fin de fichier inattendue ligne "(dernière)

Je sèche; je vais donc, soit renoncer à blinder mon script, soit devoir utiliser les tests avec if… que je voulais éviter.

Les parenthèses n’ouvrent pas de nouveaux shell sauf précédé de $. Tu devrais pouvoir utiliser les parenthèses peut être échappés par .
Mais je suis d’avis que tu devrais l’écrire sous forme if else.

Merci MisterFreez pour cette précision et effectivement, les lignes de la forme:

mount | egrep '/mnt/S_racine type' && echo 'Déja montée' ||\ ( sudo mount -t ext4 -U 543f1c11-3878-4a9f-995f-19f84166803a /mnt/SC_racine &&\ echo " montée " ) || exit 1
fonctionnent:
exit 1 agit si la commande mount renvoie une erreur et
echo " montée " dans le cas contraire

C’est faux : tldp.org/LDP/abs/html/subshells.html
Les parenthèses (avec ou sans $ devant, peu importe) ouvrent toujours un nouveau shell, les accolades jamais.
Facilement vérifiable en comptant le nombre de process bash (ps aux | grep -c bash) pendant l’exécution des deux commandes suivantes :

  1. while true; do sleep 1; done
  2. (while true; do sleep 1; done)

Je suis surpris. Je testerais peut être ce soir.

[quote]exit 1 agit si la commande mount renvoie une erreur[/quote]non, exit 1 est exécuté si grep ne retourne pas d’erreur.

man bash / Pipelines:[quote]The return status of a pipeline is the exit status of the last command,[…][/quote]

Edit:
ah ouais, non. J’ai lu trop rapidement, mais un peu de clarté ne nuirait pasif mount | egrep '/mnt/S_racine type'; then echo 'Déja montée'; else sudo mount -t ext4 -U 543f1c11-3878-4a9f-995f-19f84166803a /mnt/SC_racine && echo " montée " || exit 1; fi

L’intérêt de l’exercice était justement de se passer de if .

( je n’ai rien a priori contre if ! -mais en y réfléchissant, la ligne de commande sans if gagne en concision ce qu’elle perd peut-être en clarté quoique…- )

Elle ne perd en clarté que si on fait de l’uniligne :

if mount | egrep -q '/mnt/S_racine type'; then echo 'Déja montée'; else if sudo mount -t ext4 -U 543f1c11-3878-4a9f-995f-19f84166803a /mnt/SC_racine ; then exit 1 else echo " montée " fi fi

L’uniligne et le golfe ne servent que pour des tâches quotidiennes et encore une fonction le faire très bien.

Oui MisterFreeze, mais pouvoir faire de l’uniligne est une façon d’être rapide et efficace sans avoir à écrire un script, d’ou l’intéret de s’exercer et d’enrichir sa trousse à outil d’urgence :wink:

Bien sur, un script permet, entre autre, d’être plus lisible

je persiste : je n’ai rien contre if :stuck_out_tongue: