$#은 bash에서 무엇을 의미합니까?

$#은 bash에서 무엇을 의미합니까?

인스턴스라는 파일에 스크립트가 있습니다.

echo "hello world"
echo ${1}

그리고 다음을 사용하여 이 스크립트를 실행할 때:

./instance solfish

나는 다음과 같은 결과를 얻습니다.

hello world
solfish

하지만 내가 실행할 때 :

echo $# 

"0"이라고 적혀있습니다. 왜? 무슨 뜻인지 이해가 안 돼요 $#.

설명해주세요.

답변1

$#bash는 인수(위치 매개변수)의 수만큼 확장되는 의 특수 변수입니다 . 즉 $1, $2 ..., 문제의 스크립트에 전달되거나 인수가 셸에 직접 전달되는 경우 셸에 전달됩니다(예: in ) bash -c '...' .....

argc이는 C 와 유사합니다 .


아마도 이것은 다음과 같이 명확해질 것입니다.

$ bash -c 'echo $#'
0

$ bash -c 'echo $#' _ x
1

$ bash -c 'echo $#' _ x y
2

$ bash -c 'echo $#' _ x y z
3

bash -c0부터 시작하는 명령 다음에 인수를 취하므로( 기술적으로는 실제로 인수가 아닌 설정을 허용하는 방법일 $0뿐입니다 ) 여기서는 자리 표시자로 사용됩니다. 실제 인수는 ( ), ( ) 및 ( )입니다.bash$0_x$1y$2z$3


마찬가지로 스크립트에서(가정 script.sh) 다음이 있는 경우:

#!/usr/bin/env bash
echo "$#"

그런 다음 수행할 때:

./script.sh foo bar

스크립트는 2를 출력합니다. 비슷하게,

./script.sh foo

1이 출력됩니다.

답변2

echo $#스크립트의 위치 매개변수 수를 출력합니다.

아무것도 없으므로 0을 출력합니다.

echo $#별도의 명령이 아닌 스크립트 내부에서 유용합니다.

다음과 같은 일부 매개변수를 사용하여 스크립트를 실행하면

./instance par1 par2

echo $#스크립트에 배치하면 2가 출력됩니다 .

답변3

$#일반적으로 bash 스크립트에서 매개변수가 전달되었는지 확인하는 데 사용됩니다. 일반적으로 스크립트 시작 부분에서 매개변수를 확인합니다.

예를 들어, 오늘 작업한 스크립트의 일부는 다음과 같습니다.

if [[ $# -ne 1 ]]; then
    echo 'One argument required for the file name, e.g. "Backup-2017-07-25"'
    echo '.tar will automatically be added as a file extension'
    exit 1
fi

보고서를 요약하면 $#스크립트에 전달된 매개변수 수를 알 수 있습니다. 귀하의 경우 매개변수를 전달하지 않았으며 보고된 결과는 입니다 0.


#Bash의 다른 용도

이는 #bash에서 변수의 발생 횟수나 길이를 계산하는 데 자주 사용됩니다.

문자열의 길이를 찾으려면:

myvar="some string"; echo ${#myvar}

보고:11

배열 요소 수를 찾으려면 다음을 수행하십시오.

myArr=(A B C); echo ${#myArr[@]}

보고:3

첫 번째 배열 요소의 길이를 찾으려면 다음을 수행하십시오.

myArr=(A B C); echo ${#myArr[0]}

반환: 1(배열은 0부터 시작하는 인덱스/첨자를 사용하므로 길이가 A0인 첫 번째 요소입니다.)

답변4

$#는 인수의 개수이지만 함수에서는 다를 것이라는 점을 기억하세요.

$#스크립트, 쉘에 전달된 위치 매개변수의 수입니다.또는 쉘 기능. 이는 쉘 기능이 실행되는 동안위치 매개변수는 일시적으로 함수에 대한 인수로 대체됩니다.. 이를 통해 함수는 자신의 위치 매개변수를 받아들이고 사용할 수 있습니다.

이 스크립트는 3스크립트 자체에 전달된 인수 수에 관계없이 항상 를 인쇄합니다. 왜냐하면 "$#"함수에서 f함수에 전달된 인수 수로 확장되기 때문입니다.

#!/bin/sh

f() {
    echo "$#"
}

f a b c

이는 쉘 함수에서 위치 매개변수가 작동하는 방식에 익숙하지 않은 경우 이와 같은 코드가 예상대로 작동하지 않는다는 것을 의미하기 때문에 중요합니다.

#!/bin/sh

check_args() { # doesn't work!
    if [ "$#" -ne 2 ]; then
        printf '%s: error: need 2 arguments, got %d\n' "$0" "$#" >&2
        exit 1
    fi
}

# Maybe check some other things...
check_args
# Do other stuff...

에서는 함수 자체에 전달된 인수 수로 확장됩니다. 해당 스크립트에서는 항상 0입니다 check_args.$#

쉘 함수에서 그러한 기능을 원한다면 대신 다음과 같이 작성해야 합니다:

#!/bin/sh

check_args() { # works -- the caller must pass the number of arguments received
    if [ "$1" -ne 2 ]; then
        printf '%s: error: need 2 arguments, got %d\n' "$0" "$1" >&2
        exit 1
    fi
}

# Maybe check some other things...
check_args "$#"

$#확장되었기 때문에 작동합니다.밖의함수 중 하나로 함수에 전달됩니다.그것은위치 매개변수. 함수 내에서 $1해당 함수가 속한 스크립트가 아닌 셸 함수에 전달된 첫 번째 위치 매개변수로 확장됩니다.

따라서 와 마찬가지로 $#특수 매개변수 $1, $2등과 및 $@$*함수에서 확장될 때 함수에 전달된 인수와도 관련됩니다. 그러나$0~ 아니다함수 이름으로 변경했기 때문에 여전히 이를 사용하여 품질 오류 메시지를 생성할 수 있었습니다.

$ ./check-args-demo a b c
./check-args-demo: error: need 2 arguments, got 3

마찬가지로, 다른 함수 안에 하나의 함수를 정의하는 경우 확장이 수행되는 가장 안쪽 함수에 전달된 위치 매개변수로 작업하게 됩니다.

#!/bin/sh

outer() {
    inner() {
        printf 'inner() got %d arguments\n' "$#"
    }

    printf 'outer() got %d arguments\n' "$#"
    inner x y z
}

printf 'script got %d arguments\n' "$#"
outer p q

나는 이 스크립트를 호출 nested하고 (실행 후 chmod +x nested) 실행했습니다.

$ ./nested a
script got 1 arguments
outer() got 2 arguments
inner() got 3 arguments

네, 알아요. "1개의 인수"는 복수화 버그입니다.

위치 매개변수도 변경할 수 있습니다.

스크립트를 작성하는 경우 함수 외부의 위치 매개변수는 스크립트에 전달된 명령줄 인수가 됩니다.당신이 그들을 변경하지 않는 한.

이를 변경하는 일반적인 방법 중 하나는 shift내장을 사용하는 것입니다. 이는 각 위치 매개변수를 왼쪽으로 하나씩 이동하고 첫 번째 매개변수를 삭제하고 $#1씩 감소시킵니다.

#!/bin/sh

while [ "$#"  -ne 0 ]; do
    printf '%d argument(s) remaining.\nGot "%s".\n\n' "$#" "$1"
    shift
done
$ ./do-shift foo bar baz      # I named the script do-shift.
3 argument(s) remaining.
Got "foo".

2 argument(s) remaining.
Got "bar".

1 argument(s) remaining.
Got "baz".

내장 기능 을 사용하여 변경할 수도 있습니다 set.

#!/bin/sh

printf '%d args: %s\n' "$#" "$*"
set foo bar baz
printf '%d args: %s\n' "$#" "$*"
$ ./set-args a b c d e      # I named the script set-args.
5 args: a b c d e
3 args: foo bar baz

관련 정보