내 함수에서 $#이 항상 0인 이유는 무엇입니까?

내 함수에서 $#이 항상 0인 이유는 무엇입니까?

Bash가 나를 미치게 만들고 있습니다. 다음(그리고 예제에서 복사하여 붙여넣은 수십 가지 변형)이 작동하지 않는 이유를 이해할 수 없습니다.

#!/bin/bash

echo $#

function main {
    if (( $# < 1 )); then
        usage
    fi

    echo "good"
}

function usage {
    echo "Usage: $0 <outputdir>"
    exit 1
}

main

매개변수를 전달하고 $#예상한 대로 설정되어 있음을 분명히 알 수 있음에도 불구하고 어떤 이유로 매개변수 확인이 매번 실패합니다.

답변1

main매개변수 없이 함수를 호출하고 있습니다 . 따라서 $#주 함수에서는 항상 0입니다.

각 함수 인스턴스에는 고유한 매개변수가 있습니다. ("인스턴스"는 함수가 (재귀 호출에 의해) 여러 번 호출되는 경우 각 호출마다 고유한 매개 변수가 있음을 의미합니다.) 위치 매개 변수 $1$2및 관련 매개 변수는 $#함수 호출을 $*참조합니다 . $@예를 들어, main foo bar함수 내에서 then을 호출 하면 값은 2 가 main됩니다 .$1foo$#

스크립트에서 함수로 인수를 전달하려면 를 사용하세요 "$@". 이 구문은 스크립트(또는 함수 내에서 호출된 경우 함수)에 전달된 인수 목록으로 확장됩니다. 일반적으로 큰따옴표에서 발생하는 것과는 달리 인수는 "$@"단일 문자열이 아닌 문자열 목록으로 개별적으로 전달됩니다. 큰따옴표가 필요합니다. 그렇지 않으면 인수가 있는 그대로 전달되지 않고 공백으로 구분된 파일 이름 패턴 목록으로 처리됩니다.

function main {
  if (( $# < 1 )); then
    usage
  fi
  echo "good"
}
main "$@"

답변2

이것은 작동합니다:

#!/bin/bash
set -x
NARGS=$#

function main {
    if [ $NARGS -lt 1 ]; then
        usage
    fi

    echo good
}

function usage {
    echo "Usage: $0 <outputdir>"
    exit 1
}

main

나는 set -x일부러 그곳을 떠났다. 이러한 오류를 디버깅하는 것이 유용합니다. main함수에 인수를 전달 하지 않으면 $#함수 내에서 0이 됩니다( $NARGS이 내용을 보려면 조건에서 with로 바꾸세요).$#if

관련 정보