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.