여러 사용자 입력을 반복하려고 할 때 예기치 않은 출력이 나타나는 이유는 무엇입니까? [복사]

여러 사용자 입력을 반복하려고 할 때 예기치 않은 출력이 나타나는 이유는 무엇입니까? [복사]

저는 다음 bash 쉘 스크립트를 작성하고 있습니다.

#!/bin/bash

declare -i N
read N
for i in {1..$N}
do
  echo "Number: $i"
done

declare -i N(나는 정수를 만든다고 믿는다 N)

그러나 이 명령을 실행하면 다음과 같은 출력이 나타납니다.

>vim new.sh
>chmod +x passgen.sh
>./passgen.sh
15
Number: {1..15}

여기서는 사용자로부터 한계를 얻은 다음 루프를 실행하고 싶습니다.

답변1

에서 man bash:

확장 순서는 중괄호 확장, 매개변수 및 변수 확장, 산술 확장, 명령 대체(왼쪽에서 오른쪽으로 수행됨)입니다.

보시다시피 중괄호 확장이 먼저 나오므로 분명히 귀하의 질문에서 건너 뛰었습니다. 나는 다른 루프를 사용할 것입니다.

답변2

버팀대 확장의 문제점이 지적되었지만 나는 단지 다음과 같이 언급하고 싶습니다.

(나는 -i N 진술이 N을 정수로 만든다고 믿습니다)

나는 대답할 것입니다. 그렇습니다. 명령 주입 취약점이 되기 때문에 문제가 됩니다. 이 정수 속성을 설정하면 변수에 값이 할당될 때마다 해당 값이 산술 표현식으로 해석됩니다.

사용자가 a[$(reboot)]read프롬프트를 입력하면 다시 시작이 시도됩니다.

bash이는 산술 표현식을 평가할 zsh때 흔히 발생하는 문제입니다 ksh. for (( i = 1; i <= N; i++ ))ksh93 스타일 형식( 포함 여부에 관계없이 )을 사용하더라도 declare -i N의 내용이 N여전히 해당 산술적 맥락에서 평가되기 때문에 문제가 발생할 수 있습니다.

for i in {1..$N}declare -i Nksh, zsh 또는 yash -o braceexpand(횡설수설을 반복하지만 명령 주입 취약점을 유발하지 않는)에서는 괜찮을 것입니다(없음). 또는 sh구현 shksh.

#! /bin/sh -
IFS= read -r N
i=1; while [ "$i" -lt "$N" ]; do
  printf '%s\n' "Number: $n"
done

ksh[피연산자는 여전히 -lt산술 표현식으로 처리되므로 명령 주입 취약점이 여전히 발생합니다. // [[ $i -lt $N ]]or도 사용하지 마세요 .(( i < N ))bashzshksh

또는 루프를 수행하기 위해 적절한 프로그래밍 언어를 사용하거나 입력을 먼저 정리할 수 awk있습니다 .perl

관련 정보