정의된 문자 목록의 배열로 $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
.
제 질문은 다음과 같습니다.
- 위의 zsh bash 동작에 대한 문제를 누군가 나에게 설명해 줄 수 있습니까?
- 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}")