`$@` 및 `$*` 동작

`$@` 및 `$*` 동작

이것배쉬 매뉴얼설명하다:

에 대한:$*

큰따옴표 내에서 확장이 발생하면 단일 단어로 확장되며 각 인수의 값은 IFS특수 변수의 첫 번째 문자로 구분됩니다. 즉, 변수 value 의 첫 번째 문자는 where "$*"와 동일합니다 ."$1c$2c..."cIFS

에 대한:$@

큰따옴표 내에서 확장이 발생하면 각 인수가 별도의 단어로 확장됩니다. 즉, "$@"와 같습니다 "$1" "$2" ....

IFS변수 값의 첫 번째 문자를 제공합니다.사실, 이 두 가지 특정 매개변수가 서로 다른 동작을 생성하는 공간에서는 예를 생각할 수 없는 것 같습니다. 누구든지 IFS다른 동작을 생성하는 예제(변경 없이)를 제공할 수 있습니까 ?

여전히 약간 혼란스러운 내 테스트는 다음과 같습니다.

#!/usr/bin/env bash
# File: test.sh
# set foo and bar in the global environment to $@ and $*

test_expansion () {
  foo="$@"
  bar="$*"
}

이제 테스트해 보세요:

. test.sh
test_expansion a b c d
# foo is $@
# bar is $*

for e in "$foo"; do
  echo "$e"
done
# a b c d

for e in "$bar"; do
  echo "$e"
done
# a b c d

답변1

IFS 문자가 포함된 명령줄에서 인수(예: 공백이 있는 인수)를 전달할 때 차이가 발생합니다. 차이점을 보려면 다음 스크립트를 확인하세요.

#!/bin/bash

echo 'Here is $*'
for x in "$*"; do
    echo "  !${x}!"
done

echo ""
echo 'And here is $@'
for x in "$@"; do
    echo "  !${x}!"
done

exit 0

이제 공백을 사용하여 매개변수를 전달할 때의 차이점을 확인하세요.

./testspace01.sh "This is" a test
Here is $*
  !This is a test!

And here is $@
  !This is!
  !a!
  !test!

업데이트 아, 명령줄에서 전달된 내용을 변수에 할당하면 약간의 문제가 발생합니다. :)

명령줄에 전달된 모든 항목은 배열이라는 점을 기억하세요. 따라서 문자열에 배열을 할당하는 것은 배열에 서명하는 것과 다릅니다. 또한 별표를 사용하는지 별표를 사용하는지에 따라 배열이 다르게 처리됩니다. 다음은 내 스크립트의 업데이트된 버전입니다.

#!/bin/bash

s_star="$*"
echo 'Here is s_star'
for x in "${s_star}"; do
    echo "  !${x}!"
done

a_star=("$*")
echo ""
echo 'Here is a_star'
for x in "${a_star}"; do
    echo "  !${x}!"
done

s_at="$@"
echo ""
echo 'Here is s_at'
for x in "${s_at}"; do
    echo "  !${x}!"
done

a_at=("$@")
echo ""
echo 'Here is a_at (using star)'
for x in "${a_at[*]}"; do
    echo "  !${x}!"
done

echo ""
echo 'Here is a_at (using at)'
for x in "${a_at[@]}"; do
    echo "  !${x}!"
done

exit 0

출력은 다음과 같습니다.

./testspace02.sh "This is" a test
Here is s_star
  !This is a test!

Here is a_star
  !This is a test!

Here is s_at
  !This is a test!

Here is a_at (using star)
  !This is a test!

Here is a_at (using at)
  !This is!
  !a!
  !test!

보시다시피 다양한 동작이 있습니다.

답변2

이 시도:

#!/bin/bash
show-difference () {
    for e in "$@" ; do
        printf '<%s>\n' "$e"
    done
    for e in "$*" ; do
        printf '[%s]\n' "$e"
    done
}

show-difference {a..h}

산출:

<a>
<b>
<c>
<d>
<e>
<f>
<g>
<h>
[a b c d e f g h]

"$*"는 단일 단어이고 "$@"모든 인수는 단일 단어로 확장됩니다. 또한 "$@"이는 매개변수에 IFS의 첫 번째 문자가 포함되어 있는 경우에도 작동합니다.

답변3

set -- "hello there" bumblebee

printf '%s\n' "$@"
printf '%s\n' "$*"

결과:

hello there
bumblebee

이어서

hello there bumblebee

이는"$@"목록"$*"작은 따옴표로 묶인 문자열을 생성하는 동안 개별적으로 따옴표로 묶인 요소입니다 .

this 를 사용하면 bash여러 명령줄 인수를 사용하는 짧은 쉘 스크립트로 이를 설명할 수도 있습니다.

#!/bin/bash

IFS='_'

atarray=( "$@" )
stararray=( "$*" )

printf 'at: %s\n' "${atarray[@]}"
printf 'star: %s\n' "${stararray[@]}"

실행하세요:

$ bash ./script.sh "one two" three four
at: one two
at: three
at: four
star: one two_three_four

이는 또한 를 사용하면 확장에 의해 생성된 문자열의 요소를 구분하기 위해 "$*"의 값(첫 번째 문자만)을 사용함을 나타냅니다.$IFS

관련 정보