Bash에서 오류가 발생합니다. 8행: $1: 바인딩되지 않은 변수

Bash에서 오류가 발생합니다. 8행: $1: 바인딩되지 않은 변수

나는 구문 분석된 입력이 있는 스크립트를 가질 수 있도록 getopts를 사용하는 방법을 배우려고 노력하고 있습니다(비록 getopts가 더 나을 수도 있다고 생각하지만). 파티션 사용률을 반환하는 간단한 스크립트를 작성하려고 합니다. 문제는 내 bash 함수 중 하나가 $1함수 내에서 변수로 참조하는 함수를 좋아하지 않는 것 같다는 것입니다 . 내가 인용한 이유 는 함수에 모든 마운트 지점을 표시하는 대신 표시할 선택적 인수로 마운트 지점을 전달할 수 있기 $1때문입니다 .get_percent

스크립트

#!/usr/bin/bash

set -e
set -u
set -o pipefail

get_percent(){
    if [ -n "$1" ] 
    then
        df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
    else
        df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
    fi
}

usage(){
    echo "script usage: $(basename $0) [-h] [-p] [-m mount_point]" >&2
}

# If the user doesn't supply any arguments, we run the script as normal
if [ $# -eq 0 ];
then
    get_percent
    exit 0
fi
# ...

산출

$ bash thing.sh
thing.sh: line 8: $1: unbound variable

$ bash -x thing.sh
+ set -e
+ set -u
+ set -o pipefail
+ '[' 0 -eq 0 ']'
+ get_percent
thing.sh: line 8: $1: unbound variable

답변1

set -u아직 설정되지 않은 변수를 참조하면 설명한 대로 정확하게 중단됩니다. 인수 없이 스크립트를 호출하므로 get_percent인수 없이 호출하므로 $1설정이 해제됩니다.

함수를 호출하기 전에 이것을 확인하거나 기본 확장을 사용하십시오( ${1:-default}아직 다른 것으로 설정되지 않은 경우 다른 것으로 확장됩니다).default

답변2

이것이 효과입니다 set -u.

$#함수 내부를 확인하여 $1설정되지 않은 경우 참조를 회피할 수 있습니다.

$#이를 통해 여러 매개변수에 액세스 할 수 있습니다 . 전역적 맥락에서는 스크립트의 인수 개수이고, 함수에서는 함수의 인수 개수입니다.

질문의 맥락에서는 다음과 같습니다.

if [ $# -ge 1 ] && [ -n "$1" ]
then
    df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
else
    df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
fi

먼저 평가 한 다음 확인하므로 [ $# -ge 1 ] && [ -n "$1" ]and 를 사용해야 합니다 .[ $# -ge 1 -a -n "$1" ]$1$#

답변3

다른 답변에서는 이 효과를 언급했습니다 set -u. 다른 답변 중 어느 것도 set -u다음과 같이 되돌릴 수 있다고 언급하지 않습니다 set +u.

$ echo $VAR  # nothing echoed below as VAR is unset:

$ set -u
$ echo $VAR
bash: VAR: unbound variable
$ set +u
$ echo $VAR  # nothing echoed below as VAR is unset:

답변4

이것이 bash설정에 대한 확인을 우회하고 다음을 사용할 수 있기 때문에 다음과 같습니다(첫 번째 인수는 모든 인수입니다. 큰따옴표로 묶으면 값이 없으면 완전히 사라져 캡처되지 않습니다).$1"$@"$1$@set -u

get_percent() {
    df -h "$@" | awk 'NR>1 { printf "%s\t%s\n", $1, $5 }'
}

출력하는 두 값 사이에 {space}{tab}{space}가 나오지 않고 {tab}만 나오도록 나머지 줄도 살짝 조정했습니다. 정말로 두 개의 보이지 않는 공간을 원한다면 awkuse로 변경하세요 printf "%s \t %s\n", $1, $5.

관련 정보