zsh 무작위 생성기의 이상한 동작

zsh 무작위 생성기의 이상한 동작

정의된 문자 목록의 배열로 $1 자리의 혼합 임의 문자를 생성하는 이 스크립트가 있습니다.

#!/bin/bash

charlist1=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
charlist2=(0 1 2 3 4 5 6 7 8 9)
charlists=(${charlist1[*]} ${charlist2[*]})

i="1"
while [ $i -le $1 ]; do
    out=$out`echo -n ${charlists[$(($RANDOM % ${#charlists[*]}))]}`
    i=$(( i + 1 ))
done

echo $out

Bash에서는 잘 작동하지만 zsh로 호출하면 zsh that_script_above.sh 6다음과 같이 동일한 문자로 6자리 숫자가 생성됩니다.

>>> zsh that_script_above.sh 6
llllll
>>> zsh that_script_above.sh 6
bbbbbb

스크립트를 다음과 같이 수정하면:

#!/bin/bash

charlist1=(a b c d e f g h i j k l m n o p q r s t u v w x y z)
charlist2=(0 1 2 3 4 5 6 7 8 9)
charlists=(${charlist1[*]} ${charlist2[*]})

i="1"
while [ $i -le $1 ]; do

    echo -n ${charlists[$(($RANDOM % ${#charlists[*]}))]}

    i=$(( i + 1 ))
done

echo

bash및 에서 예상했던 대로 훌륭하게 작동합니다 zsh.

제 질문은 다음과 같습니다.

  1. 위의 zsh bash 동작에 대한 문제를 누군가 나에게 설명해 줄 수 있습니까?
  2. bash에서 사용자 정의 가능한 변수와 함께 for 루프를 사용하는 방법은 무엇입니까? for i in {1..$1}bash에서는 작동 하지 않는 것 같습니다 .

답변1

Q1. 명령 대체(백틱)는 서브쉘을 사용하며 zsh에서는 서브쉘의 RNG 상태가 다시 시드되지 않습니다. 상위 셸에서 사용 하지 않고 새 하위 셸을 반복적으로 생성하므로 $RANDOM각 하위 셸에서 동일한 값을 얻습니다. 바라보다:
https://stackoverflow.com/questions/32577117/references-to-random-in-subshells-all-returning-identical-values
https://superuser.com/questions/1210435/ Different-behavior-of-in-zsh-and-bash-functions

명령 대체 및 에코가 필요하지 않으며 $((..))배열 첨자가 이미 산술 표현식으로 평가되었기 때문에 필요하지 않지만 zsh 배열은 1-원점이므로 +1이 필요합니다(0에 도달하지 않은 것은 운이 좋습니다).

 out=$out${charlists[ $RANDOM % ${#charlists[*]} + 1 ]}

또한: 명령 내 대체가 필요한 경우에도 echo그렇지 않습니다. -n왜냐하면 명령 대체 자체가 캡처되고 대체된 데이터에서 후행 줄 바꿈을 제거하기 때문입니다.

Q2. bash는 인수 확장(및 명령 및 산술 대체/확장) 전에 중괄호 확장을 수행하지만 zsh(및 ksh)는 그 후에 수행합니다. yucky 또는 yucky를 사용할 수 있지만 for i in $(seq 1 $1)내장된for i in $(eval "echo {1..$n}")

관련 정보