OVH Cloud OVH Cloud

bash et test d'une expression

19 réponses
Avatar
Hugolino
Bonjour (et Noyeux Joël)


J'ai un script bash qui fabrique une page html, index de mes photos.

Ce script est mal écrit (car je suis nul en langage de script...) et
depuis que j'ai installé la nouvelle Ubuntu 6.10, mon script foire.

Tout semble venir de ma manière de comparer une variable.

Dans mon script j'ai:
Date=""
Date=`identify -format %[EXIF:DateTime] "$ResultConvertFile"`
if [[ x$Date = "x" || x$Date = "xunknown" ]]
then
echo " Donnée EXIF sur la date indisponible"
Date="Date non enregistrée"
else
echo " Date : "$Date
fi

et l'exécution du script affiche:
[: 491: missing ]
/usr/local/bin/GeneThumb: 491: [[: not found
/usr/local/bin/GeneThumb: 491: x2006:09:02: not found
Date : 2006:09:02 19:51:44.

(la ligne 491 contenant juste "done", soit la fin de la boucle sur mon
fichier de photos et identify etant une commande du package imagemagick
qui permet de lire les données EXIF de la photo)

Bref, comment comparer une variable dans un script bash ?

En supplément, et comme cadeau de Noël, j'aimerais bien un cours sur la
différence entre les trois tests suivants:
* if [[ ]]
* if (( ))
* if [ ]

Ma page de man de bash est en anglais et je sens que des subtilités
m'échappent...


Merci

--
L'intelligence artificielle ne remplacera jamais la connerie humaine.

9 réponses

1 2
Avatar
Hugolino
Le Tue, 26 Dec 2006 16:48:10 +0100, Raphaël SEBAN a écrit:
if [ ! "$Date" ] || [ "$Date" = 'unknown' ] ; then


En fait ce préfère ce style-là...

mais c'est bof bof je trouve ;)


... pourquoi ?



AMHA ça n'est pas très "élégant" au sens
mathématique du terme.

Autrement dit, ça oblige à écrire bcp de
code alors qu'on pourrait en écrire
nettement moins pour dire exactement la
même chose.

Mais bon. C'est un avis personnel.


...et tout à fait respectable.

Merci encore pour ton aide (ainsi qu'à Marc et Michel)


--
$ rm *>o
$ ls
o
Hugo (né il y a 1346604611 secondes)



Avatar
Stephane Chazelas
2006-12-26, 13:06(+00), Michel Talon:
Hugolino wrote:

Pas grave. Mais la page de man de bash parle effectivement de double
crochets:
http://pages.videotron.com/bash/doc/manbashfr.html
«[[ expression ]]
Renvoie 1 ou 0 selon la valeur de la condition expression.»

Donc je ne sais toujours pas quand il faut mettre des simples ou des
doubles (sauf à procéder par essais-erreurs)


Oui, mais si tu regardes la page man de sh sur un autre système, par
exemple FreeBSD tu ne trouves pas mention du [[. Tu en déduis que [[ est
encore une basherie à fuir comme la peste. Par contre le simple [ est un
synonyme bien connu de "test", et en tant que tel utilisable partout et
documenté dans "man test". Il me semble que se ramener toujours au plus
simple et au plus général est la bonne voie.
[...]


Pas une basherie, une ksherie reprise (plus ou moins a
l'identique) par zsh et bash.

"[" est une commande. Comme beaucoup de personnes ignorent la
syntaxe du shell et la commande "[" elle meme est bugguée dans
le design, Korn a introduit la structure [[ ... ]], c'est un
ajout d'une nouvelle syntaxe au shell. "[[" n'est pas une simple
commande, n'est pas parsee pareil. Ce qui est a l'interieur a
une syntaxe specifique qui se veut plus intuitive que la syntaxe
normale d'une commande simple (comme "["). [[ ... ]] (le tout)
est une commande dans le sens qu'elle a un code de retour, peut
etre redirigee...

[[ ... ]] n'est pas standard. "[" est suffisant et fiable dans
la mesure ou on n'utilise pas -o ou -a (mais les "||" et "&&" du
shell a la place) qu'on sait /quoter/ ses variables. Meme pour
les "[" non-POSIX comme celui des sh des BSDs/ash, c'est fiable
si on ecrit [ "x$a" = "x$b" ] ou lieu de [ "$a" = "$b" ].

if [ -z "$var" ] || [ Unknown = "$var" ]; then
...
fi



case $var in
("" | Unknown) ...;;
esac


--
Stéphane


Avatar
Olivier Miakinen

case $var in
("" | Unknown) ...;;
esac


Oh ! On peut mettre une parenthèse ouvrante au début ? Si oui, cela
m'arrangera beaucoup pour le « matching » des parenthèses avec %
dans vi.

Tiens, en effet, le man de bash indique que la parenthèse ouvrante est
possible quoique optionnelle :
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

Qu'en est-il des autres shells ?

Avatar
talon
Olivier Miakinen <om+ wrote:

case $var in
("" | Unknown) ...;;
esac


Oh ! On peut mettre une parenthèse ouvrante au début ? Si oui, cela
m'arrangera beaucoup pour le « matching » des parenthèses avec %
dans vi.

Tiens, en effet, le man de bash indique que la parenthèse ouvrante est
possible quoique optionnelle :
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

Qu'en est-il des autres shells ?


Ici avec le shell standard de FreeBSD:
niobe% /bin/sh
$ case $SHELL in
(toto) echo toto;;
(*sh) echo $SHELL;;
esac
/usr/local/bin/zsh

avec zsh:
niobe% case $SHELL in
case> (toto) echo toto;;
case> (*sh) echo $SHELL;;
case> esac
/usr/local/bin/zsh
et ksh marche aussi.

--

Michel TALON


Avatar
Olivier Miakinen

Oh ! On peut mettre une parenthèse ouvrante au début ? [...]
Qu'en est-il des autres shells ?


Ici avec le shell standard de FreeBSD:
[...]
avec zsh:
[...]
et ksh marche aussi.


Je revérifierai avec l'ensemble des shells sur les différents Unix sur
lesquels je suis amené à travailler, mais cela me donne de bons espoirs.
Merci beaucoup à toi pour ces premiers essais, et peut-être encore plus
à Stéphane pour m'avoir fait découvrir cette possibilité.


Avatar
Marc
Olivier Miakinen wrote:

Je revérifierai avec l'ensemble des shells sur les différents Unix sur
lesquels je suis amené à travailler, mais cela me donne de bons espoirs.


Comme d'habitude ça ne marche pas avec le /bin/sh de solaris, mais tu
n'en as pas forcément besoin.

Avatar
Olivier Miakinen

Je revérifierai avec l'ensemble des shells sur les différents Unix sur
lesquels je suis amené à travailler, mais cela me donne de bons espoirs.


Comme d'habitude ça ne marche pas avec le /bin/sh de solaris, mais tu
n'en as pas forcément besoin.


Je n'en ai effectivement pas besoin : c'est ksh par défaut sur nos Solaris.


Avatar
Stephane Chazelas
2006-12-27, 21:46(+01), Olivier Miakinen:

case $var in
("" | Unknown) ...;;
esac


Oh ! On peut mettre une parenthèse ouvrante au début ? Si oui, cela
m'arrangera beaucoup pour le « matching » des parenthèses avec %
dans vi.

Tiens, en effet, le man de bash indique que la parenthèse ouvrante est
possible quoique optionnelle :
case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

Qu'en est-il des autres shells ?


C'est POSIX, donc ca marchera avec tous les sh POSIX des Unix.

Ca ne marche pas avec le Bourne shell (l'ancetre des sh
modernes) et des vieilles versions de ash/FreeBSD/NetBSD-sh (une
reimplementation libre du Bourne shell initialement).

--
Stéphane


Avatar
Stephane Chazelas
2006-12-28, 12:50(+00), Marc:
Olivier Miakinen wrote:

Je revérifierai avec l'ensemble des shells sur les différents Unix sur
lesquels je suis amené à travailler, mais cela me donne de bons espoirs.


Comme d'habitude ça ne marche pas avec le /bin/sh de solaris, mais tu
n'en as pas forcément besoin.


Le /bin/sh de Solaris est un Bourne shell, il n'est la que pour
backward compatibility. Le sh de Solaris se trouve dans
/usr/xpg4/bin (et est en fait un ksh).

--
Stéphane


1 2