L'affectation des variables shell échappe automatiquement à '['

0

J'essaie de déterminer si une chaîne contient une expression régulière dans shell ( bash).
Plus précisément, s'il contient un chiffre.
Et pendant que ça:

$ [[ string_with[6]indice =~ [0-9] ]] && echo "True" || echo "False"

fonctionne comme prévu. Lorsque j'assigne des variables LHS et RHS, il se passe quelque chose d'étrange:

$ STR=string_with[6]indice
$ REGEX=[0-9]
$ [[ string_with[6]indice =~ [0-9] ]] && echo "True" || echo "False"
False

Je voulais voir à quoi le shell dépensait mes variables et ai découvert ceci:

$ STR=string_with[6]indice
+ STR='string_with[6]indice'
$ REGEX=[0-9]
+ REGEX='[0-9]'
$ [[ $STR =~ "$REGEX" ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ \[0-9] ]]
+ echo False
False

Où cette \devant [0-9]provenir, et pourquoi la coquille échapper automatiquement la première tranche [en REGEX?

so.very.tired
la source
Tout cela est un peu irrationnel: j'ai fait quelques tests et peu importe que vous fassiez une double citation $STRou non (à moins qu'il y ait un blanc incorporé), mais citer $REGEXdonne ce que vous observez, tout en omettant les guillemets. La double citation du modèle de recherche littérale se comporte de la même manière. J'imagine qu'il y aura des problèmes s'il y a un nom de fichier à un chiffre dans le répertoire actuel. Je voudrais citer entre les deux affectations variables pour éviter cela.
AFH

Réponses:

1

C'est parce que vous avez des guillemets doubles $REGEX. Lors de la mise en correspondance avec l' =~opérateur, les sections citées du motif sont traitées littéralement. C'est-à-dire que les méta-caractères regex dans les sections citées sont traités comme s'ils avaient été échappés. Comparez l'effet lorsque le motif est entre guillemets:

$ # Pattern in variable, quoted:
$ [[ $STR =~ "$REGEX" ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ \[0-9] ]]
+ echo False
False
$ # Pattern directly in command, quoted:
$ [[ $STR =~ "[0-9]" ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ \[0-9] ]]
+ echo False
False

avec l'effet sans guillemets:

$ # Pattern in variable, NOT quoted:
$ [[ $STR =~ $REGEX ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ [0-9] ]]
+ echo True
True
$ # Pattern directly in command, NOT quoted:
$ [[ $STR =~ [0-9] ]] && echo "True" || echo "False"
+ [[ string_with[6]indice =~ [0-9] ]]
+ echo True
True

C'est l'un des rares cas où vous ne souhaitez pas citer une référence de variable.

BTW, je recommande l'utilisation de noms de variables en minuscules ou en majuscules dans les scripts shell; De cette façon, vous ne courez pas le risque d'entrer en conflit avec une variable d'environnement qui a une signification particulière pour le shell ou d'autres programmes ( $PATHc'est l'exemple classique).

Gordon Davisson
la source