bash 명령 행 인수에 액세스 $ @ vs $ *


327

많은 SO 질문과 bash 자습서에서 bash 스크립트의 명령 줄 args에 두 가지 방법으로 액세스 할 수 있음을 알았습니다.

$ ~ >cat testargs.sh 
#!/bin/bash

echo "you passed me" $*
echo "you passed me" $@

결과 :

$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2

차이점은 무엇이며 $*그리고 $@?
전자는 언제 사용해야하고 후자는 언제 사용해야합니까?


이 답변을 살펴보십시오 : stackoverflow.com/a/842325/671366
코드 작성

Alexli의 정적 분석 echo "something $@"은 오류로 취급 됩니다
Alex Cohn

답변:


437

특수 매개 변수가 인용 될 때 차이가 나타납니다. 차이점을 설명하겠습니다.

$ set -- "arg  1" "arg  2" "arg  3"

$ for word in $*; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in $@; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in "$*"; do echo "$word"; done
arg  1 arg  2 arg  3

$ for word in "$@"; do echo "$word"; done
arg  1
arg  2
arg  3

인용의 중요성에 대한 또 다른 예 : "arg"와 숫자 사이에 2 개의 공백이 있지만 $ word를 인용하지 않으면 다음과 같이하십시오.

$ for word in "$@"; do echo $word; done
arg 1
arg 2
arg 3

그리고 bash에서 "$@"반복하는 "기본"목록은 다음 과 같습니다.

$ for word; do echo "$word"; done
arg  1
arg  2
arg  3

65
+1 나는 항상이 개념이 배쉬 매뉴얼이 완전히없는 간단한 예제로 가장 잘 설명되었다고 생각했다.
chepner

5
가능한 유스 케이스가 $*있거나 "$*"필요할 수 있으며 목적이 $@또는에 의해 제공 될 수 "$@"없는가?
anishsane

5
스크립트 매개 변수가 새 명령의 매개 변수가되어야하는 "래퍼"스크립트에 더 적합한 버전은 무엇입니까?
Segfault

7
이 경우 @Segfault는 항상 "$@"따옴표로 선택하십시오 .
glenn jackman 16:30에

2
이 답변에는 유용한 예제가 포함되어 있지만 그 뒤에 메커니즘을 설명하면 더 좋습니다. 이렇게 작동합니까?
Lii

255

Bash Hackers Wiki 의 멋진 편리한 개요 테이블 :

$ * 대 $ @ 테이블

여기서 c세 번째 행은의 첫 번째 문자 인 $IFSInternal Field Separator (쉘 변수)입니다.

인수가 스크립트 변수에 저장되고 인수에 공백이 포함될 것으로 예상 "$*"되면 내부 필드 구분 기호 $IFS를 tab으로 설정하여 트릭을 사용하는 것이 좋습니다 .


42
... "C"는 $ IFS의 첫 번째 문자입니다
글렌 잭맨

39
... 그리고 $IFS의미 "내부 필드 분리."
Sroo Stroobandt

다음은 인용 된 입력을 포함 하는 예 입니다. 입력도 중요합니다!
Sroo Stroobandt

랩핑 된 명령의 기능을 모방하는 것 외에는 아무것도하지 않는 랩퍼 스크립트를 작성하려고한다고 가정하십시오. 래퍼 스크립트에서 내부 명령으로 인수를 전달하는 데 어떤 구문을 사용해야합니까?
마리노스

44

$ *

위치 매개 변수부터 시작하여 위치 매개 변수로 확장됩니다. 큰 따옴표 내에서 확장이 발생하면 각 매개 변수의 값이 IFS 특수 변수의 첫 문자로 구분되어 단일 단어로 확장됩니다. 즉, "$ *"는 "$ 1c $ 2c ..."와 같습니다. 여기서 c는 IFS 변수 값의 첫 문자입니다. IFS가 설정되지 않은 경우 매개 변수는 공백으로 구분됩니다. IFS가 널인 경우 매개 변수는 중간 구분 기호없이 결합됩니다.

$ @

위치 매개 변수부터 시작하여 위치 매개 변수로 확장됩니다. 큰 따옴표 내에서 확장이 발생하면 각 매개 변수가 별도의 단어로 확장됩니다. 즉, "$ @"은 "$ 1" "$ 2"와 같습니다. 큰 따옴표로 묶인 확장이 단어 내에서 발생하면 첫 번째 매개 변수의 확장은 원래 단어의 시작 부분과 확장됩니다. 마지막 매개 변수의 단어는 원래 단어의 마지막 부분과 결합됩니다. 위치 매개 변수가 없으면 "$ @"및 $ @는 아무것도 확장하지 않습니다 (즉, 제거됨).

출처 : 배쉬 맨


15

$ @는 $ *와 동일하지만 각 매개 변수는 따옴표로 묶인 문자열입니다. 즉, 매개 변수는 해석이나 확장없이 그대로 전달됩니다. 이는 무엇보다도 인수 목록의 각 매개 변수가 별도의 단어로 표시됨을 의미합니다.

물론 "$ @"는 인용해야합니다.

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST


1

이 예에서는 "at"와 "asterix"의 차이점을 강조 표시 할 수 있습니다. 나는 "과일"과 "야채"두 배열을 선언

fruits=(apple pear plumm peach melon)            
vegetables=(carrot tomato cucumber potatoe onion)

printf "Fruits:\t%s\n" "${fruits[*]}"            
printf "Fruits:\t%s\n" "${fruits[@]}"            
echo + --------------------------------------------- +      
printf "Vegetables:\t%s\n" "${vegetables[*]}"    
printf "Vegetables:\t%s\n" "${vegetables[@]}"    

위의 코드에서 다음 결과를 참조하십시오.

Fruits: apple pear plumm peach melon
Fruits: apple
Fruits: pear
Fruits: plumm
Fruits: peach
Fruits: melon
+ --------------------------------------------- +
Vegetables: carrot tomato cucumber potatoe onion
Vegetables: carrot
Vegetables: tomato
Vegetables: cucumber
Vegetables: potatoe
Vegetables: onion

6
과학적으로 말하면 토마토는 과일입니다.
랜디

1
당신이 맞아요! "식물학에서 과일은 개화 후 난소에서 형성된 개화 식물 (혈관 정자라고도 함)의 씨앗 함유 구조입니다." en.wikipedia.org/wiki/
과일

@ 랜디 : 과학적으로 말하면 모든 과일은 야채입니다 ( "식물"과 동의어입니다).
Cris Luengo

@CrisLuengo 이단! :)
랜디
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.