
왜?
for i in {1..5}; do x="${i}" echo "$x"; done
출력되지 않음
1
2
3
4
5
?
이를 수행하는 올바른 방법은 무엇입니까?
(테스트됨for i in {1..5}; do x=$(i) echo "$x"; done
-bash: i: 명령을 찾을 수 없습니다
다른 사람)
답변1
귀하의 질문에 질문에 답하기
왜 ,,,,, 가
for i in {1..5}; do x="${i}" echo "$x"; done
출력1
되지 않나요 ?2
3
4
5
그 이유는 실행 중에 작업이 평가되는 순서와 관련이 있기 때문입니다. 이 명령을 보세요
x="${i}" echo "$x"
이것이 하는 일은
- 변수를 해당 값으로 대체
- 변수에 임시 값 할당
x
- 명령을 실행하세요
그래서 당신은 얻습니다
x=1 echo ""
(또는x=2 echo ""
등)- 이 명령이 실행되는 동안
x
다음 값으로 설정됩니다.1
- 명령이 실행됩니다:
echo ""
아마도 이 명령은 에 값을 할당하고 해당 값을 출력하라는 두 가지 명령을 의미했을 것입니다 x
. 그러나 쉘 구문에서 작성한 내용은 완벽하게 합법적인 코드이므로 쉘은 이의 없이 이를 실행했습니다.
답변2
다음 두 가지 질문에 대한 답변을 요청하셨습니다.
현재 코드가 예상한 출력을 생성하지 않는 이유에 대한 설명을 요청하셨습니다.
예상되는 출력을 생성할 수 있도록 코드를 작성하는 올바른 방법을 요청하셨습니다.
귀하의 코드를 보면 귀하가 코드를 작성한 방식에 대한 두 가지 설명을 볼 수 있습니다.
내용에 대해 약간의 혼란이 있을 수 있습니다.for 루프의 구문.
평가 순서에 대해 약간의 혼동이 있을 수 있습니다.간단한 명령.
for 루프 구문
첫 번째 경우에는 변수 할당 후에 세미콜론이 누락되었다고 말하고 싶습니다. for 루프를 한 줄에 작성하려면 루프 본문의 각 명령 뒤에 세미콜론을 넣어야 합니다. 대신 이것을 시도해 보세요:
for i in {1..5}; do x="${i}"; echo "$x"; done
또 다른 대안은 세미콜론 대신 개행 문자를 사용하는 여러 줄 구문을 사용하여 for 루프를 작성하는 것입니다.
for i in {1..5}
do
x="${i}"
echo "${x}"
done
세미콜론과 개행 문자를 혼합하여 사용할 수도 있습니다. 예:
for i in {1..5}; do
x="${i}"; echo "${x}"
done
간단한 명령 평가
x="$i"
두 번째 경우에는 명령 프롤로그의 변수 할당(즉 할당)이 명령 본문의 변수 확장(즉 ${x}
in 의 확장)보다 먼저 발생한다고 가정했을 것입니다 echo "${x}"
. 그러나 실제로는 그렇지 않습니다. 이를 확인하려면 다음 페이지를 참조하세요.간단한 명령 확장Bash 매뉴얼이나간단한 명령에 대한 하위 섹션에서Posix 사양. 이 두 참고 문헌에는 모두 다음 구절이 포함되어 있습니다.
"간단한 명령"은 임의의 순서로 선택적인 변수 할당 및 리디렉션의 시퀀스이며 선택적으로 단어 및 리디렉션이 뒤따르고 제어 연산자에 의해 종료됩니다.
주어진 간단한 명령을 실행해야 할 때(즉, AND-OR 목록이나사례명령문이 단순 명령을 우회하지 않은 경우) 다음 확장, 할당 및 리디렉션은 명령 텍스트의 시작 부분부터 끝까지 모두 수행됩니다.
2단계에서는 명령의 변수 확장이 발생하지만 1단계에서는 3단계와 4단계까지 변수 할당이 저장된다는 점을 알려줍니다. 따라서 할당이 발생하기 전에 표현식이 echo "${x}"
확장됩니다 . 이는 빈 출력이 나타나는 이유를 설명합니다.echo ""
x="${i}"
이 주제에 대한 자세한 내용은 다음 게시물을 참조하세요.
답변3
에서는 할당이 무조건적인 Bourne 연산자 의 zsh
세 번째 형식을 사용합니다 (var가 설정되지 않거나 비어 있는 경우에만 반대).${var::=value}
${var=value}
${var:=value}
for i in {1..5}; do echo ${x::=$i}; done
또는:
for i ({1..5}) echo ${x::=$i}
안에 bash
:
set -o posix # so the value of x remains after eval returns
for i in {1..5}; do x=$i eval 'echo "$x"'; done
즉, $x
확장이 포함된 코드가 평가될 때 설정되어 있어야 합니다.
여기와 같은 십진 정수 값의 경우 다음을 수행할 수도 있습니다.
for i in {1..5}; do echo "$((x = i))"; done
또는 빈 문자열로 ${var:=value}
설정한 후 언제든지 Bourne 연산자를 사용할 수 있습니다 .x
for i in {1..5}; do x=; echo "${x:=$i}"; done