it-source

Bash 스크립트에 전달된 인수 수 확인

criticalcode 2023. 4. 26. 23:25
반응형

Bash 스크립트에 전달된 인수 수 확인

필요한 인수 수가 충족되지 않을 경우 Bash 스크립트에서 오류 메시지를 출력합니다.

저는 다음 코드를 시도했습니다.

#!/bin/bash
echo Script name: $0
echo $# arguments 
if [$# -ne 1]; 
    then echo "illegal number of parameters"
fi

알 수 없는 이유로 다음 오류가 발생했습니다.

test: line 4: [2: command not found

내가 뭘 잘못하고 있는 거지?

다른 간단한 명령과 마찬가지로[ ... ]또는test에는 인수 사이에 공백이 필요합니다.

if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
fi

또는

if test "$#" -ne 1; then
    echo "Illegal number of parameters"
fi

제안들

Bash에 있을 때는 사용하는 것을 선호합니다.[[ ]]변수에 대한 단어 분할 및 경로 이름 확장을 수행하지 않기 때문에 식의 일부가 아니면 따옴표가 필요하지 않을 수 있습니다.

[[ $# -ne 1 ]]

또한 인용되지 않은 조건 그룹화, 패턴 매칭(확장된 패턴 매칭)과 같은 다른 기능도 있습니다.extglob) 및 정규식 일치.

다음 예제에서는 인수가 유효한지 확인합니다.하나 또는 두 개의 인수를 허용합니다.

[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]

순수 산술 표현식의 경우, 사용(( ))어떤 사람들에게는 여전히 더 나을 수 있지만, 그들은 여전히 가능합니다.[[ ]]와 같은 산술 연산자를 사용하여.-eq,-ne,-lt,-le,-gt또는-ge식을 단일 문자열 인수로 배치합니다.

A=1
[[ 'A + 1' -eq 2 ]] && echo true  ## Prints true.

만약 당신이 그것을 다른 기능들과 결합할 필요가 있다면 도움이 될 것입니다.[[ ]]뿐만 아니라.

참고:[[ ]]그리고.(( ))와 동일한 수준의 구문 분석을 수행하는 키워드입니다.if,case,while,그리고.for.

또한 Dave가 제안했듯이 stdout이 리디렉션될 때 오류 메시지가 포함되지 않도록 stderr로 전송되는 것이 좋습니다.

echo "Illegal number of parameters" >&2

스크립트 종료

잘못된 매개 변수가 스크립트에 전달될 때 스크립트를 종료하는 것도 논리적입니다.이것은 이미 ekangas에 의해 댓글에 제안되었지만 누군가가 이 답변을 가지고 있도록 편집했습니다.-1반환된 값으로, 그래서 나는 그것을 제대로 하는 것이 낫습니다.

-1에 대한 주장으로 Bash에 의해 받아들여졌지만.exit명시적으로 문서화되어 있지 않으며 일반적인 제안으로 사용하기에는 적합하지 않습니다. 64에 정의되어 있기 때문에 가장 공식적인 값이기도 합니다.sysexits.h와 함께#define EX_USAGE 64 /* command line usage error */대부분의 도구는 다음과 같습니다.ls역시 리턴2무효 주장으로나는 또한 돌아오곤 했습니다.2내 대본에서 하지만 최근에 나는 더 이상 신경 쓰지 않았고, 단순히 사용했습니다.1모든 실수로하지만 그냥 자리를 잡자구요.2가장 일반적이고 OS에 특정되지 않은 경우가 많기 때문입니다.

if [[ $# -ne 1 ]]; then
    echo "Illegal number of parameters" >&2
    exit 2
fi

레퍼런스

숫자를 다룰 때는 산술식을 사용하는 것이 좋을지도 모릅니다.

if (( $# != 1 )); then
    >&2 echo "Illegal number of parameters"
fi

>&2오류 메시지를 stderr에 쓰는 데 사용됩니다.

[]: !=, =, == ...에는 문자열 비교 연산자가 있고 -eq, -gt...에는 산술 이진수가 있습니다.

다음을 사용합니다.

if [ "$#" != "1" ]; then

또는:

if [ $# -eq 1 ]; then

특정 인수가 누락된 경우에만 보석에 관심이 있는 경우 매개 변수 대체가 유용합니다.

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

다음을 사용하여 작동하는 간단한 하나의 라이너를 수행할 수 있습니다.

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main

이는 다음과 같이 요약됩니다.

  1. bash 변수에서 $# 매개 변수의 크기를 테스트합니다. $#는 1이 아닙니다(하위 명령 수).
  2. true이면 usage() 함수를 호출하고 상태 1로 종료합니다.
  3. 그렇지 않으면 main() 함수를 호출합니다.

주의할 사항:

  • usage ()는 단순 에코 "$0: params"일 수 있습니다.
  • 주 스크립트는 하나의 긴 스크립트일 수 있습니다.

이 바시 치트 시트를 확인해 보세요, 많은 도움이 될 것입니다.

하려면 전된인길이확를인면려다사다음니용합을하수달을 사용합니다."$#"

의 배열을 하려면 된인배열사을용면다사다음용니합을려하전수달의다▁to▁passed를 사용합니다."$@"

길이를 확인하고 반복하는 예는 다음과 같습니다.

myFunc() {
  if [[ "$#" -gt 0 ]]; then
    for arg in "$@"; do
      echo $arg
    done
  fi
}

myFunc "$@"

이 기사는 저에게 도움이 되었지만, 저와 저의 상황에 대해 몇 가지를 놓치고 있었습니다.이것이 누군가에게 도움이 되기를 바랍니다.

여기서 매개 변수가 하나만 지정되어 있는지 확인하는 간단한 하나의 라이너입니다. 그렇지 않으면 스크립트를 종료합니다.

[ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit

여기에 많은 좋은 정보가 있지만, 저는 제가 유용하다고 생각하는 간단한 토막글을 추가하고 싶습니다.

위의 것들과 어떻게 다릅니까?

  • stdout에 인쇄하는 것보다 적합한 stderr에 사용을 인쇄합니다.
  • 다른 답변에 언급된 종료 코드와 함께 반환
  • 하나의 라이너로 만들어지지 않습니다...
_usage(){
    _echoerr "Usage: $0 <args>"
}

_echoerr(){
    echo "$*" >&2
}

if [ "$#" -eq 0 ]; then # NOTE: May need to customize this conditional
    _usage
    exit 2
fi
main "$@"

#!/bin/bash

Help() {
  echo "$0 --opt1|-opt1 <opt1 value> --opt2|-opt2 <opt2 value>"
}

OPTIONS=($@)
TOTAL_OPTIONS=$#
INT=0

if [ $TOTAL_OPTIONS -gt 4 ]
then
        echo "Invalid number of arguments"
        Help
        exit 1
fi

while [ $TOTAL_OPTIONS -gt $INT ]
do
        case ${OPTIONS[$INT]} in

                --opt1 | -opt1)
                        INT=`expr $INT + 1`
                        opt1_value=${OPTIONS[$INT]}
                        echo "OPT1 = $opt1_value"
                        ;;

                --opt2 | -opt2)
                        INT=`expr $INT + 1`
                        opt2_value=${OPTIONS[$INT]}
                        echo "OPT2 = $opt2_value"
                        ;;

                --help | -help | -h)
                        Help
                        exit 0
                        ;;

                *)
                        echo "Invalid Option - ${OPTIONS[$INT]}"
                        exit 1
                        ;;

        esac
        INT=`expr $INT + 1`
done

이것이 제가 사용하는 방식이며 문제없이 작동합니다.

[root@localhost ~]# ./cla.sh -opt1 test --opt2 test2
OPT1 = test
OPT2 = test2

만약 당신이 안전한 쪽에 있고 싶다면, 저는 getopts를 사용하는 것을 추천합니다.

다음은 작은 예입니다.

    while getopts "x:c" opt; do
      case $opt in
        c)
          echo "-$opt was triggered, deploy to ci account" >&2
          DEPLOY_CI_ACCT="true"
          ;;
            x)
              echo "-$opt was triggered, Parameter: $OPTARG" >&2 
              CMD_TO_EXEC=${OPTARG}
              ;;
            \?)
              echo "Invalid option: -$OPTARG" >&2 
              Usage
              exit 1
              ;;
            :)
              echo "Option -$OPTARG requires an argument." >&2 
              Usage
              exit 1
              ;;
          esac
        done

http://wiki.bash-hackers.org/howto/getopts_tutorial 같은 자세한 내용은 여기를 참조하십시오.

테스트 조건 사이에 공백을 추가해야 합니다.

if [ $# -ne 1 ]; 
    then echo "illegal number of parameters"
fi

이것이 도움이 되길 바랍니다.

언급URL : https://stackoverflow.com/questions/18568706/check-number-of-arguments-passed-to-a-bash-script

반응형