2016-10-16 3 views
1

Ich bin ziemlich neu zu Zsh (oh-my-Zsh) und ich versuche, ein benutzerdefiniertes Thema zu schreiben. ich in ein Problem lief und reduzierte es auf den folgenden TestfallZsh-Funktion läuft nur einmal

PROMPT='$RANDOM > ' 

funktioniert wie erwartet, erzeugt sie eine Zufallszahl auf jedem Befehl. Aber bei Verwendung einer Funktion

PROMPT='$(my_random) > ' 

function my_random(){ 
    echo $RANDOM 
} 

es gibt immer die gleiche Anzahl, auch nach source ~/.zshrc immer noch die gleiche Zahl. erst wenn ich das terminalfenster schließe und es wieder öffne, bekomme ich eine neue nummer, die für die komplette session gleich bleibt.

nur, wenn ich tun:

PROMPT='$RANDOM $(my_random) > ' 

function my_random(){ 
    echo $RANDOM 
} 

i erhalten zwei Zufallszahlen als erwartet ... eine Erklärung für dieses Verhalten?

btw, ich benutze kde's konsole auf einer neuen arch installation.

bearbeiten

FWIW Ich habe mit/dev/urandom arbeitet direkt gut. Ich würde immer noch gerne wissen, was los ist.

function my_random() { 
    echo $(cat /dev/urandom | tr -dc '0-9' | head -c5) 
} 

Antwort

1

$() -Expansion geschieht in einer Subshell und Änderungen an $RANDOM in einer Subshell beeinflussen nicht die Eltern. Von zshparam (1):

Die Werte von RANDOM bilden eine absichtlich wiederholbare pseudozufällige Sequenz; Subshells, die auf RANDOM verweisen, führen zu identischen pseudozufälligen Werten, es sei denn, der Wert RANDOM wird in der Parent-Shell zwischen subshell-Aufrufen referenziert oder gesetzt.

Sie brauchen nicht zu Einstellung der Aufforderung zu drehen, es zu reproduzieren:

% echo $(echo $RANDOM) 
17454 
% echo $(echo $RANDOM) 
17454 

bash nicht Verhalten zsh ist hier nicht teilt.

Das lästige Bit ist, dass die schnelle Expansion auch in einer Subshell geschieht, so kann man nicht nur dieses Problem beheben, indem $RANDOM Referenzierung in, sagen wir, precmd. Der beste Weg, den ich finden kann, ist, es in einer leeren Erweiterung zu tun:

PROMPT='${RANDOM##*}$(my_random) > ' 
+0

Danke für die Klarstellung. Netter Trick dort mit der leeren Erweiterung. Ich denke, ich werde damit gehen. Vielen Dank! –

+0

'precmd() {: $ RANDOM; PS1 = "$ (my_random)>"; } 'sollte wie vorgesehen funktionieren. – chepner