Bash에서 명령줄 인수 반복

Bash에서 명령줄 인수 반복

누군가 이 두 코드 블록의 차이점을 설명해 줄 수 있나요? 나는 블록 #2가 블록 #1과 동일한 출력을 출력할 것이라고 생각했지만 그렇지 않습니다. 누군가 이유를 설명할 수 있나요?

# ./arguments.sh hello my name is X

블록 #1

for i
do
    echo $i
done

산출:

hello
my
name
is
X

블록 #2

args=$#
for (( i=1; i<=$args; i+=1 ))
do
    echo $i
done

산출:

1
2
3
4
5

답변1

첫 번째 블록은 (암시적으로) 명령줄 인수를 반복합니다."$@"

for i in "$@"    # same as your "for i"
do
    echo "$i"
done

두 번째 블록은 명시적으로 인수 수를 반복하고 인덱스를 인쇄합니다.

args=$#                          # number of command line args
for (( i=1; i<=$args; i+=1 ))    # loop from 1 to N (where N is number of args)
do
    echo $i
done

$#귀하의 예를 기준으로 5라고 가정하면 변수는 , , , , $i값을 사용합니다 .12345

다른 (현재 삭제된) 답변에서 지적했듯이 다음과 같이 인덱스별로 명령줄 인수를 참조할 수 있습니다.

args=$#
for (( i=1; i<=$args; i++ ))
do
    echo "$i - ${!i}"
done

답변2

엠마 루오의 답변실제 질문에 답하려면:

묻다:이 두 코드 블록의 차이점은 무엇입니까? 왜 다른 출력을 제공합니까?

ㅏ:첫 번째 루프는 명령줄 매개변수를 반복하고, 두 번째 루프는 매개변수를 반복합니다.숫자(색인).

...내 생각에 이 문제는 6~8분 후에 스스로 알아낼 수 있을 것 같습니다. 이는 명백합니다. 두 번째 프로그램이 다음과 같은 작업을 수행하기를 원할 수도 있습니다.

echo $$i                                        # This doesn't do what you want.

변수에 저장된 숫자로 색인화되고 i로 참조되는  매개변수를 표시합니다 $i. 의견에서 지적했듯이 이것은 원하는 것을 수행하지 않습니다. (그것하다뭔가를 해보세요. 시도해 보고 알아보시기 바랍니다.무엇물론. ) 그러나 이것은 실제로 작동하는 것에 가깝습니다.

eval echo \$$i                                  # Don't do this.

또는 동등하게,

eval echo '$'"$i"                               # Don't do this.

이 명령

  • i(숫자 1, 2, 3,... 중 하나)의 값을 구합니다.
  • $앞에 하나를 붙여서 $1, 등을 만듭니다 $2.$3
  • 명령을 사용하여 eval다음과 같이 말합니다. "방금 작성한 명령줄을 사용하여평가하다내가 입력하는 것처럼요.

이는 실행 효과를 갖습니다.

echo $1
echo $2
echo $3

그러나 의견에서 알 수 있듯이 이를 피하도록 노력해야 합니다.  eval입력이 일반적인 단어가 아닌 경우 위험할 수 있습니다. 사이트를 검색해 보세요. 이에 대한 설명이 많이 있습니다.

그러나 두 번째 프로그램이 첫 번째 프로그램과 동일한 작업을 수행하도록 만드는 상당히 안전한 방법이 있습니다.

echo $i

도착하다

echo ${!i}

좋아요, ${i}우선 $i. !명령과 같은 효과를 제공합니다 eval. (예: 또는 )의 값을 ${!x}찾아 사용합니다.x$x${x}저것찾을 변수의 이름입니다. 그러므로 , x=foothen 은 ${!x}과 동일합니다 $foo. 위의 코드는 동일한 작업을 수행 i하여 value라는 매개변수를 가져옵니다 i.

그런데, 그렇게 하지 않을 타당한 이유가 없고 자신이 무엇을 하고 있는지 확실히 알고 있지 않는 한 , 쉘 변수(예 : , "$i"및 ) 에 대한 모든 참조를 항상 인용해야 합니다."$#""$args""${i}""${!i}"

관련 정보