Bash 쉘 스크립트에서 입력 인수가 있는지 확인


1336

입력 인수가 있는지 확인해야합니다. 다음 스크립트가 있습니다

if [ "$1" -gt "-1" ]
  then echo hi
fi

나는 얻다

[: : integer expression expected

입력 인수 1이 있는지 먼저 확인하는 방법은 무엇입니까?

답변:


2328

그것은:

if [ $# -eq 0 ]
  then
    echo "No arguments supplied"
fi

$#변수는 당신에게 스크립트가 전달 된 입력 인수의 수를 알려줍니다.

또는 인수가 빈 문자열인지 아닌지 확인할 수 있습니다.

if [ -z "$1" ]
  then
    echo "No argument supplied"
fi

-z"$ 1"의 확장이 널 (null) 문자열인지 아닌지 스위치를 테스트합니다. 널 문자열 인 경우 본문이 실행됩니다.


62
나는이 방법을 간결한 구문으로하고 POSIX는 여전히 수용 가능합니다. [ -z "$1" ] && echo "No argument supplied" 나는 그들이 더 쉬워서 하나의 라이너를 선호한다. if
— JM Becker

168
exit 1스크립트가 작동하기 위해 인수가 필요할 때 if 블록 내부의 에코 끝에 에코 를 추가하고 싶을 것입니다 . 명백하지만 완전성에 주목할 가치가 있습니다.
— msanford

16
거의 유용하지는 않지만, 첫 번째 인수가 초기화되었지만 비어있을 수 있습니다. programname "" secondarg third. $#검사는 명확 인수의 수를 확인합니다.
— tripleee

39
멍청한 놈, 특히 비 스크립팅 배경에서 온 사람에게는 이러한 것들에 대한 특이성을 언급하는 것이 중요합니다. 당신은 또한 우리가 오프닝과 닫는 버팀대 뒤에 공백이 필요하다고 언급 할 수 있습니다. 그렇지 않으면 일이 작동하지 않습니다. 나는 나 자신을 스크립팅 멍청한 놈 (C 배경에서 왔으며) 어려운 방법으로 발견했다. 일이 저를 위해 일한 것은 "있는 그대로"전체를 복사하기로 결정한 때였습니다. 그때 나는 오프닝 버팀대 뒤에 그리고 닫는 버팀대 앞에 공백을 두어야한다는 것을 깨달았습니다.
— HighOnMeat

72
선택적인 인수if [ ! -z "$1" ]; then ...
— gcb

346

이 방법을 시연하는 것이 좋습니다

if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 1
fi

인수가 너무 적은 경우 일반적으로 종료해야합니다.


72
아닙니다. 이것은 exit 1일반적으로 원하는 것이며, [[ ]]어느 것이 더 합리적인지 테스트를 사용합니다 . 따라서 사람들이 코드를 맹목적으로 복사하여 붙여 넣는 것이 더 좋습니다.
— dshepherd

42
[]와 [[]]의 차이점에 대한 자세한 내용은 stackoverflow.com/questions/3427872/…를
— Sebastián Grignoli

103

경우에 따라 사용자가 스크립트에 인수를 전달했는지 여부를 확인해야하며 그렇지 않은 경우 기본값으로 돌아갑니다. 아래 스크립트에서와 같이 :

scale=${2:-1}
emulator @$1 -scale $scale

사용자가 scale두 번째 매개 변수로 전달하지 않은 경우 -scale 1기본적으로 Android 에뮬레이터를 시작 합니다. ${varname:-word}확장 연산자입니다. 다른 확장 연산자도 있습니다.

  • ${varname:=word}값 을 반환하는 대신 undefined 를 설정 합니다 .varnameword
  • ${varname:?message}varname정의되고 null이 아닌 경우 반환 하거나 message스크립트를 인쇄 하고 스크립트를 중단합니다 (예 : 첫 번째 예).
  • ${varname:+word}이 정의되고 null이 아닌 word경우에만 반환 합니다 varname. 그렇지 않으면 null을 반환합니다.

1
위의 예는을 사용하는 것 같습니다 ${varname?message}. 여분 :의 오타입니까, 아니면 행동이 바뀌나요?
— Eki

6
Eki에서 ":"는 기본 제공 명령이며이 예에서 / bin / true의 약어입니다. 기본적으로 제공되는 인수를 무시하는 수행 할 수없는 명령을 나타냅니다. 이 테스트에서는 인터프리터가 "$ varname"의 내용을 실행하려고하지 않도록해야합니다 (확실히 원하지는 않음). 또한 주목할 가치가 있습니다. 이 방법으로 원하는만큼 변수를 테스트 할 수 있습니다. 그리고 모두 특정 오류 메시지가 있습니다. 즉: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
— user.friendly

48

시험:

 #!/bin/bash
 if [ "$#" -eq  "0" ]
   then
     echo "No arguments supplied"
 else
     echo "Hello world"
 fi

4
$#및에 큰 따옴표가 필요한 이유는 무엇 0입니까?
— user13107

1
큰 따옴표없이 $ # 및 0과 같이 사용하면 아무런 문제가 없습니다.
— Ranjithkumar T

Windows에서는 mingw가 유일한 방법입니다.
— Lajos Meszaros 2016 년

2
이 답변은 방금 만든 스크립트의 훌륭한 시작점을 제공합니다. 을 보여 주셔서 감사합니다 else.
— Chris K

2
bash에서 @ user13107 큰 따옴표로 묶인 변수는 글 로빙 (예 : 파일 이름 확장 foo*) 및 단어 분리 (값에 공백이 포함 된 경우 내용 분할)를 방지합니다. 이 경우 $#두 경우 모두 적용되지 않으므로 견적을 제시 할 필요 가 없습니다. 인용 0부호도 필요하지 않지만 일부 사람들은 실제로 문자열이기 때문에 값을 인용하는 것을 선호합니다.
— Dennis

39

인수가 스크립트에 전달되었는지 감지하는 다른 방법 :

((!$#)) && echo No arguments supplied!

주 (( expr ))식의 원인은의 규칙에 따라 평가하는 쉘 산술 .

인수가 없을 때 종료하려면 다음과 같이 말할 수 있습니다.

((!$#)) && echo No arguments supplied! && exit 1

위의 또 다른 (유사한) 방법은 다음과 같습니다.

let $# || echo No arguments supplied

let $# || { echo No arguments supplied; exit 1; }  # Exit if no arguments!

help let 말한다 :

let: let arg [arg ...]

  Evaluate arithmetic expressions.

  ...

  Exit Status:
  If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.

2
-1 인수의 존재를 검증하는 경우 이것이 최악의 방법 일 수 있습니다.
— user.friendly 3

2
exit내 zsh 프로세스를 죽이는 대신 return죽이지 않는 것을 사용 합니다.
— Timo

((!$#))히스토리 대체를 유발하는 이유는 무엇 입니까?
— Zhro

25

간단한 스크립트에이 스 니펫을 자주 사용합니다.

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "\nPlease call '$0 <argument>' to run this command!\n"
    exit 1
fi

1
따라서 이것은 하나의 인수 만 필요로 사용됩니다.
— Danijel

21

지적해야 할 더 많은 기준이 있기 때문에 단순히 문자열이 null인지 테스트 할 수 있다고 덧붙입니다.

if [ "$1" ]; then
  echo yes
else
  echo no
fi

마찬가지로 arg count를 기대한다면 마지막 테스트를하십시오.

if [ "$3" ]; then
  echo has args correct or not
else
  echo fixme
fi

arg 또는 var와 마찬가지로


4

인수가 존재하는지 확인하려면 인수 수가 인수 인수 수보다 크거나 같은지 확인할 수 있습니다.

다음 스크립트는 이것이 어떻게 작동하는지 보여줍니다

test.sh

#!/usr/bin/env bash

if [ $# -ge 3 ]
then
  echo script has at least 3 arguments
fi

다음과 같은 출력을 생성합니다

$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments

3

작은 말씀 드리지만, 배쉬 숫자 테스트 연산자는 정수 작업 ( -eq, -lt, -ge, 등)

나는 $ vars가 int 인 것을 보장하고 싶다.

var=$(( var + 0 ))

테스트하기 전에 "[: integer arg required"오류를 방지하기 위해.


1
깔끔한 트릭이지만주의하십시오 : bash가 산수에서 부동 소수점을 처리 할 수 ​​없기 때문에이 방법은 구문 오류를 발생시키고 0이 아닌 값을 반환 할 수 있습니다. var=$(printf "%.0f" "$var")부동 소수점을 처리 할 수 ​​있지만 문자열이 주어지면 0이 아닌 종료로 고통받습니다. 당신이 awk를 신경 쓰지 않는다면, 내가 사용하는이 방법은 정수를 시행하는 데 가장 강력한 것 같습니다 : var=$(<<<"$var" awk '{printf "%.0f", $0}'). var가 설정되어 있지 않으면 기본값은 "0"입니다. var가 float이면 가장 가까운 정수로 반올림됩니다. 음수 값도 사용하기에 좋습니다.
— user.friendly

0

하나의 라이너 bash 기능 검증

myFunction() {

    : ${1?"forgot to supply an argument"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

기능 이름 및 사용법 추가

myFunction() {

    : ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

정수인지 확인하기 위해 유효성 검사 추가

예를 들어 전달 된 인수가 정수인지 확인하기 위해 유효성 검사를 추가하려면 유효성 검사 함수를 호출하도록 유효성 검사 한 라이너를 수정하십시오.

: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"

그런 다음 인수의 유효성을 검사하여 성공시 0, 실패시 1, 실패시 스크립트를 중단하는 die 함수를 반환하는 유효성 검사 함수를 구성합니다.

validateIntegers() {

    if ! [[ "$1" =~ ^[0-9]+$ ]]; then
        return 1 # failure
    fi
    return 0 #success

}

die() { echo "$*" 1>&2 ; exit 1; }

더 간단합니다-그냥 사용하십시오 set -u

set -u 참조 된 모든 변수가 사용될 때 설정되므로 변수를 설정하고 잊어 버립니다.

myFunction() {
    set -u
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.