Разница в генерации случайных значений в подоболочках zsh и bash

avatar
manolius
1 июля 2021 в 19:32
68
1
1

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

Рассмотрите следующий код:

$ cat script.sh
#!/bin/zsh

checkFieldConvergence () {
  echo $RANDOM
  echo $RANDOM
}

echo $(checkFieldConvergence)
echo $(checkFieldConvergence)
echo $(checkFieldConvergence)
checkFieldConvergence
checkFieldConvergence
checkFieldConvergence

$ ./script.sh
4049 24768
4049 24768
4049 24768
4049
24768
20764
3330
17114
1195

то же самое с bash дает

$ cat script.sh
#!/bin/bash

checkFieldConvergence () {
  echo $RANDOM
  echo $RANDOM
}

echo $(checkFieldConvergence)
echo $(checkFieldConvergence)
echo $(checkFieldConvergence)
checkFieldConvergence
checkFieldConvergence
checkFieldConvergence

$ ./script.sh
12274 28155
27609 10269
14100 14662
6945
17897
20354
29817
14495
27552
Источник

Ответы (1)

avatar
KamilCuk
1 июля 2021 в 19:48
2

почему zsh генерирует одно и то же случайное значение при вызове подоболочки

Bash определяет, запущен ли он в подоболочке, и если это так, bash повторно заполняет генератор случайных чисел, используя текущее значение gettimeofday(), в то время как Zsh не выполняет повторное заполнение генератора и просто вызывает rand().

References: https://github.com/bminor/bash/blob/f3a35a2d601a55f337f8ca02a541f8c033682247/variables.c#L1371 , https://github.com/bminor/bash/blob/ f3a35a2d601a55f337f8ca02a541f8c033682247/lib/sh/random.c#L87 vs https://github.com/zsh-users/zsh/blob/00d20ed15e18f5af682f0daec140d6b8383c479a/Src/params.c#L4294 .

Для действительно случайного числа, отличающегося между вложенными оболочками, используйте SRANDOM.

manolius
1 июля 2021 в 20:05
0

Что касается SRANDOM, я вижу, что он поставляется с новым BASH 5.1 и может быть установлен извне: например, в Ubuntu. Некоторые люди используют srand() в AWK. Но ничего не могу найти на Zsh. Есть ли альтернативный способ изменить семя в Zsh? Я мог бы изменить семя в определении функции, например

KamilCuk
1 июля 2021 в 20:13
0

Старый добрый cat /dev/urandom | .... вроде coderhelper.com/a/1195035/9072753

manolius
1 июля 2021 в 20:20
0

Спасибо за помощь

manolius
1 июля 2021 в 20:31
0

Для будущих посетителей, из ссылки, предоставленной KamilCuk, лучшая команда практическая с использованием /dev/urandom не находится в ответе с наибольшим количеством голосов, и это od -A n -t d -N 1 /dev/urandom |tr -d ' '

user1934428
2 июля 2021 в 09:39
0

@manolius: я случайным образом задаю генератор случайных чисел в моем .zshrc, выполняя RANDOM=$(($(od -vAn -N2 -tu2 < /dev/urandom))). Если вы хотите сделать это и для неинтарактивных оболочек, сделайте это вместо .zshenv.