Mustervergleich in einem bedingten ZSH-Ausdruck

Mustervergleich in einem bedingten ZSH-Ausdruck

Ich habe Probleme mit der Musterübereinstimmung in der Hook-Funktion von zsh precmd. Ich habe Folgendes:

precmd(){
   local x='test'
   if [ $x = '*test*' ]; then
      echo 'hello'
   fi
}

das niemals „Hallo“ ausgibt. Ich habe diesen Code mit einem normalen Code getestet, zsh test.zshder einwandfrei funktioniert, und ich habe ihn ohne den regulären precmdAusdruck probiert und auch das Ergebnis war einwandfrei. Irgendeine Ahnung, warum das nicht wie erwartet funktioniert?

$ zsh --version
zsh 4.3.11 RHEL 

Antwort1

[ $x = '*test*' ]testet, ob die Zeichenfolge, die sich aus der Erweiterung ergibt $x, also ist text, gleich der Zeichenfolge ist, die sich aus der Erweiterung ergibt '*test*', also ist *text*.

Um zu testen, ob der Wert der Variablen xmit demMuster *test*müssen Sie den =oder ==Operator von verwendenZSH-bedingte Ausdrücke, die innerhalb geschrieben sinddoppelte Klammern [[ … ]]. Außerdem dürfen Sonderzeichen im Muster nicht in Anführungszeichen gesetzt werden, da sie sonst für sich selbst stehen. Also:

if [[ $x == *test* ]]; then …

Die Syntax von bedingten Ausdrücken ähnelt der Syntax von Ausdrücken, die Sie in einfachen Klammern verwenden können [ … ], ist aber nicht identisch. [wird wie ein gewöhnlicher Befehl analysiert; tatsächlich handelt es sich um einen integrierten Befehl mit einem einstelligen Namen, der identisch ist mit demtesteingebautaußer dass [am Ende ein zusätzliches Argument erforderlich ist, das lauten muss ]. [[ … ]]ist eine eindeutige grammatikalische Konstruktion, die die Verwendung von Shell-Sonderzeichen darin zulässt. würde zur Liste der übereinstimmenden Dateinamen [ $x = *test* ]erweitert (Globbing) und die integrierte Funktion würde das Ergebnis davon analysieren. wird als Teil der Analyse bedingter Ausdrücke analysiert , wodurch kein Globbing aufgerufen wird.*test*test[[ $x = *test* ]]*test*

Antwort2

*test*ist kein gültiges Regex-Muster. Das *ist ein Wiederholungsoperator und braucht etwas, das wiederholt werden kann. Es ist sehr wahrscheinlich, dass Sie wollen .*test.*, obwohl das bei Regex nicht notwendig ist, da es standardmäßig nicht verankert ist. Sie könnten einfach nach suchentest

Sie können jedoch keine Regex-Muster mit dem =Operator abgleichen, Sie benötigen =~.

precmd () {
   local x=test
   if [[ $x =~ test ]]; then
      echo 'hello'
   fi
}

verwandte Informationen