функция zsh запускается только один раз

Я новичок в zsh (oh-my-zsh) и пытаюсь написать собственную тему. Я столкнулся с проблемой и сократил ее до следующего теста

PROMPT='$RANDOM > '

работает так, как ожидалось, он выдает случайное число для каждой команды. Но при использовании функции

PROMPT='$(my_random) > '

function my_random(){
    echo $RANDOM
}

он всегда возвращает один и тот же номер, даже после source ~/.zshrc все тот же номер. только когда я закрываю окно терминала и открываю его снова, я получаю новый номер, который остается неизменным для всего сеанса.

только когда я делаю:

PROMPT='$RANDOM $(my_random) > '

function my_random(){
    echo $RANDOM
}

я получаю два случайных числа, как и ожидалось... какое объяснение этому поведению?

Кстати, я использую консоль kde при установке новой арки.

Изменить

Кстати, я обнаружил, что использование /dev/urandom напрямую работает хорошо. Я все еще хотел бы знать, что происходит.

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

person Holger Will    schedule 16.10.2016    source источник


Ответы (2)


$()-расширение происходит в подоболочке, и изменения $RANDOM в подоболочке не влияют на родителя. Из зшпарам(1):

Значения RANDOM образуют преднамеренно повторяемую псевдослучайную последовательность; вложенные оболочки, которые ссылаются на RANDOM, приведут к идентичным псевдослучайным значениям, если только значение RANDOM не будет задано или задано в родительской оболочке между вызовами подоболочки.

Вам не нужно обращаться к настройке приглашения, чтобы воспроизвести его:

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

bash не разделяет здесь поведение zsh.

Раздражает то, что расширение подсказки также происходит в подоболочке, поэтому вы не можете просто исправить это, сославшись на $RANDOM, скажем, в precmd. Лучший способ, который я могу найти, - это сделать это в пустом расширении:

PROMPT='${RANDOM##*}$(my_random) > '
person Ry-♦    schedule 16.10.2016
comment
Благодарю за разъяснение. Хороший трюк с пустым расширением. Я думаю, что я пойду с этим. Спасибо! - person Holger Will; 17.10.2016
comment
precmd () { : $RANDOM; PS1="$(my_random) >"; } должно работать по назначению. - person chepner; 17.10.2016

Как сказано в комментарии от chepner, вы можете исправить это, поместив : $RANDOM; в свой precmd. Это приводит к тому, что значение $RANDOM берется и создается новое.

e.g.

precmd() {
   : $RANDOM;
   ...
}
person Nate Levin    schedule 02.04.2021