web-dev-qa-db-fra.com

Comment annuler un test avec des expressions régulières dans un script bash?

Avec GNU bash (version 4.0.35 (1) -release (x86_64-suse-linux-gnu)), je voudrais annuler un test avec des expressions régulières. Par exemple, j'aimerais ajouter conditionnellement un chemin à la variable PATH, si le chemin n’y est pas déjà, comme dans:

TEMP=/mnt/silo/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
export PATH

Je suis sûr qu'il y a un million de façons de le faire, mais j'aimerais savoir si le conditionnel peut être annulé d'une manière ou d'une autre, comme dans (erroné):

TEMP=/mnt/silo/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
export PATH
142
David Rogers

Vous avez eu raison, il suffit de laisser un espace entre le ! et le [[ comme if ! [[

154
SiegeX

Vous pouvez également placer le point d'exclamation entre les crochets:

if [[ ! $PATH =~ $temp ]]

mais vous devriez ancrer votre modèle pour réduire les faux positifs:

temp=/mnt/silo/bin
pattern="(^|:)$temp(:|$)"
if [[ ! $PATH =~ $pattern ]]

qui cherche une correspondance au début ou se termine par deux points avant ou après celle-ci (ou les deux). Je recommande d'utiliser des noms de variables en minuscules ou en majuscules pour réduire le risque de collision de noms avec les variables Shell.

107
Dennis Williamson

le moyen le plus sûr est de mettre le! pour la négation de regex dans le [[ ]] comme ça:

if [[ ! ${STR} =~ YOUR_REGEX ]]; then

sinon, il pourrait échouer sur certains systèmes.

17

Oui, vous pouvez nier le test car SiegeX a déjà indiqué.

Cependant, vous ne devriez pas utiliser d'expressions régulières pour cela - cela peut échouer si votre chemin contient des caractères spéciaux. Essayez ceci à la place:

[[ ":$PATH:" != *":$1:"* ]]

(Source)

7
Mark Byers

J'aime simplifier le code sans utiliser d'opérateurs conditionnels dans de tels cas:

TEMP=/mnt/silo/bin
[[ ${PATH} =~ ${TEMP} ]] || PATH=$PATH:$TEMP
4
dimir