
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.zsh
der einwandfrei funktioniert, und ich habe ihn ohne den regulären precmd
Ausdruck 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 x
mit 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 demtest
eingebautauß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
}