Jai des problèmes pour comprendre la correspondance de modèle de chaîne avec = ~ in bash .
Jai écrit la fonction suivante ( ne vous inquiétez pas – cest juste une expérience dexpérimentation, pas une approche de sécurité avec md5sum):
md5 () { [[ "$(md5sum $1)" =~ $2* ]] && echo fine || echo baarr; }
et la testé avec une entrée. Voici quelques références:
md5sum wp.laenderliste b1eb0d822e8d841249e3d68eeb3068d3 wp.laenderliste
Il est inutilement difficile de comparer, si la source de la somme de contrôle ne contient pas déjà les deux blancs avec le nom de fichier. « s doù proviennent les observations, mais mon observation est plus intéressante que les nombreuses façons de résoudre ce problème:
Je définis une variable de contrôle et teste ma fonction avec des chaînes trop courtes mais correspondantes:
ok=b1eb0d822e8d841249e3d68eeb3068d3 for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i} ;done fine fine fine fine
Cela « est attendu et très bien, puisque cest le but de la fonction, dignorer la non-concordance des » wp.laenderliste « manquants et donc des discordances encore plus longues .
Maintenant, si jajoute des éléments aléatoires, qui ne correspondent pas, jattends, bien sûr, des erreurs, et je les reçois:
for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i}GU ;done baarr baarr baarr baarr
Comme prévu. Mais lorsquil ny a quun seul, dernier caractère incompatible , voyez ce qui se passe:
for i in {29..32}; do md5 wp.laenderliste ${ok:1:$i}G ;done fine fine fine fine
Est-ce moi, ne réalisant pas comment cela est censé fonctionner (sélectionner est cassé), ou y a-t-il vraiment une erreur hors-un-par-un dans la correspondance de modèle de bash?
Les incohérences au milieu de la chaîne sont importantes à partir du compte 1:
for i in 5 9 e ; do echo md5 wp.laenderliste ${ok//$i/_} ;done md5 wp.laenderliste b1eb0d822e8d841249e3d68eeb3068d3 md5 wp.laenderliste b1eb0d822e8d84124_e3d68eeb3068d3 md5 wp.laenderliste b1_b0d822_8d841249_3d68__b3068d3 for i in 5 9 e ; do md5 wp.laenderliste ${ok//$i/_} ;done fine baarr baarr
La version bash:
bash -version GNU bash, Version 4.3.48(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2013 Free Software Foundation, Inc. Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl.html>
Clause de non-responsabilité : md5sum nest utile que contre les erreurs involontaires, pas contre les attaques. Je nencourage pas à lutiliser.
Et cette question nest pas une recherche de meilleures solutions ou solutions de contournement. Il sagit de = ~ Opérateur, sil doit agir comme il le fait et si oui, pourquoi.
Réponse
=~
in ([[ ]]
) est une correspondance de modèle dexpression régulière (ou plutôt, une recherche , voir ci-dessous ). Cest différent de =
(ou ==
) qui utilise les mêmes modèles que les caractères génériques de nom de fichier.
Dans en particulier, lastérisque dans les expressions régulières signifie « zéro ou une copie de lunité précédente », donc abc*
signifie ab
plus zéro ou plus c
s.
Dans votre cas, lastérisque de fin rend le caractère final de largument de fonction facultatif. Dans votre dernier exemple, le modèle devient ...68d3G*
, et comme G*
correspond à la chaîne vide, il correspond à une chaîne comme ...68d3
. Regexese pour » toute chaîne « est de .*
, ou » nimporte quel caractère, nimporte quel nombre de fois « .
Notez que la correspondance dexpression régulière recherche une correspondance nimporte où dans la chaîne, elle ne le fait pas « Il nest pas nécessaire que ce soit la chaîne entière . Ainsi, le modèle cde
se trouverait dans la chaîne abcdefgh
.
Vous voudrez peut-être utiliser quelque chose comme ceci:
[[ "$(md5sum "$1")" = "$2 "* ]] && echo ok
Nous navons pas vraiment besoin dune correspondance dexpression régulière ici, et puisque md5sum
renvoie lespace de fin ( plus filename) de toute façon, nous pouvons lutiliser dans le modèle pour vérifier que nous correspondons au modèle complet. Donc, donner à la fonction un hachage tronqué ne correspondrait pas.
Commentaires
- Oh, maintenant je me sens sale. Je travaille principalement avec sed, lorsque jutilise la correspondance de motifs. Là, bien sûr, je dois utiliser. * et le savoir. Dune manière ou dune autre, jai appris lidée manifestement erronée, que jai oublier le point dans le shell – que ‘ nest que le cas pour la correspondance de nom de fichier, non? Dans le cas où / esac, le point est également nécessaire? I ‘ Jai lair si stupide, maintenant!;)
- @userunknown,
case
utilise les mêmes modèles que pour le nom de fichier correspond, donc*
correspond à tout, et le point nest que le point. Je pense que=~
est à peu près le seul endroit dans le shell qui utilise des expressions rationnelles. (Ensuite, bien sûr, ksh / Zsh / Bash ont des globes étendus qui ont à peu près les mêmes fonctionnalités que les expressions rationnelles, mais avec une syntaxe différente. Il doit être explicitement activé dans Bash, cependant.) - On pourrait aussi faire
[ "$(md5sum < "$1")" = "$2 -" ]
pour supprimer la dépendance sur ksh / zsh / bash (et éviter les problèmes avec les fichiers dont le nom commence par-
). - Ok, cest une bonne excuse. Donc, la mémoire approximative, cette correspondance de motif dans le shell est compliquée, était au moins juste. Maintenant je me sens beaucoup mieux. 🙂 Maintenant, jai essayé
= $2.*
et cela fonctionne aussi, mais » $ 2 » * le ferait être meilleur.Mais ce n’était qu’une expérience, alors j’ai gagné ‘ à utiliser autre chose que l’expérience d’apprentissage.
Réponse
Je nutiliserais pas de regex ici, juste une comparaison de chaînes:
md5 () { sum=$(md5sum "$1" | awk "{print $1}") [[ $sum = "$2" ]] && echo fine || echo baarr; }