bash에서 $ #는 무엇을 의미합니까? 다음을 사용 하여이 스크립트를

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

echo "hello world"
echo ${1}

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

./instance solfish

나는이 출력을 얻는다 :

hello world
solfish

그러나 내가 달릴 때 :

echo $# 

“0”이라고 표시되어 있습니다. 왜? 무슨 $#뜻 인지 모르겠습니다 .

설명해주세요.



답변

$#bash인수의 수 (위치 매개 변수)로 확장 되는 특수 변수입니다 . 즉, 인수 $1, $2 ...가 쉘에 직접 전달 된 경우 (예 : in) 해당 스크립트 또는 쉘에 전달됩니다 bash -c '...' .....

이것은 argcC 와 비슷합니다 .


아마도 이것은 분명해질 것입니다 :

$ 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( $1), y( $2) 및 z( $3)입니다.


마찬가지로 다음과 같은 script.sh경우 스크립트 (가정 )에서

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

그런 다음에 할 때 :

./script.sh foo bar

스크립트는 2를 출력합니다; 마찬가지로,

./script.sh foo

1을 출력합니다.


답변

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

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

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

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

./instance par1 par2

echo $#스크립트가 출력 2에 위치.


답변

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

예를 들어 다음은 오늘 작업 한 스크립트의 스 니펫입니다.

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

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


#배쉬의 다른 용도

#종종 발생 횟수 또는 가변 길이를 계산하는 떠들썩한 파티에서 사용된다.

문자열의 길이를 찾으려면

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

보고: 11

배열 요소 수를 찾으려면

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

보고: 3

첫 번째 배열 요소의 길이를 찾으려면

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

반환 값 : 1( A배열은 0부터 시작하는 인덱스 / 첨자를 사용하므로, 길이는 0입니다.)


답변

$# 인수의 수이지만 함수에서 다를 수 있음을 기억하십시오.

$#스크립트, 쉘 또는 쉘 함수에 전달 된 위치 매개 변수의 수입니다 . 쉘 함수가 실행되는 동안 위치 매개 변수가 함수의 인수로 임시 대체 되기 때문 입니다. 이를 통해 함수는 자체 위치 매개 변수를 승인하고 사용할 수 있습니다.

이 스크립트 는 함수 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...

에서 check_args, $#해당 스크립트에 항상 0입니다 기능 자체에 전달 된 인수의 수를 확장합니다.

쉘 기능에서 이러한 기능을 원한다면 다음과 같이 작성해야합니다.

#!/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