선택적 입력 인수를 사용하는 bash 스크립트를 작성하는 방법은 무엇입니까?


471

스크립트가 선택적 입력을받을 수 있기를 원합니다.

예를 들어 현재 내 스크립트는

#!/bin/bash
somecommand foo

그러나 나는 그것을 말하고 싶습니다 :

#!/bin/bash
somecommand  [ if $1 exists, $1, else, foo ]

3
배쉬 또는 POSIX? Bash를 사용하면 더 많은 가능성이 있습니다
user123444555621

@ Pumbaa80 bash-태그를 업데이트했습니다.
Abe


답변:


705

기본값 구문을 사용할 수 있습니다.

somecommand ${1:-foo}

위의 내용은 Bash Reference Manual-3.5.3 Shell Parameter Expansion [emphasis mine]에 설명되어 있습니다.

매개 변수가 설정되지 않거나 null이면 단어 확장이 대체됩니다. 그렇지 않으면 매개 변수 값이 대체됩니다.

매개 변수가 설정되지 않은 경우 (기본값이 아닌 경우 (예 : 빈 문자열이 아닌 경우)) 기본값을 바꾸려면이 구문을 대신 사용하십시오.

somecommand ${1-foo}

Bash Reference Manual-3.5.3 에서 다시 셸 매개 변수 확장 :

콜론을 생략하면 설정되지 않은 매개 변수에 대해서만 테스트가 수행됩니다. 다시 말해, 콜론이 포함되면 연산자는 매개 변수의 존재 여부와 그 값이 널이 아닌지 테스트합니다. 콜론이 생략되면 연산자는 존재 여부 만 테스트합니다.


52
"반환 위의 명령 사이의 의미 적 차이를주의 foo경우 $1설정 해제 또는 빈 문자열 "및 ${1-foo}"반환 foo하는 경우이 $1설정되지."
l0b0

12
이것이 왜 작동하는지 설명 할 수 있습니까? 특히 ':'및 '-'의 기능 / 목적은 무엇입니까?
jwien001 2016 년

8
@ jwein001 : 위에서 제출 한 답변에서 변수가 정의되지 않은 경우 대체 연산자를 사용하여 기본값을 반환합니다. 구체적으로 논리는 "$ 1이 있고 null이 아닌 경우 값을 반환하고 그렇지 않으면 foo를 반환합니다."입니다. 콜론은 선택 사항입니다. 생략하면 "존재하고 null이 아닙니다"만 "존재"로 변경하십시오. 빼기 부호는 $ 1을 'foo'로 설정하지 않고 foo를 반환하도록 지정합니다. 대체 연산자는 확장 연산자의 하위 클래스입니다. 로빈스와 비비의 섹션 6.1.2.1 참조 클래식 쉘 스크립팅 [오라일리 ( shop.oreilly.com/product/9780596005955.do )
Jubbles

5
@Jubbles 또는 간단한 참조를 위해 책 전체를 사고 싶지 않다면 ... tldp.org/LDP/abs/html/parameter-substitution.html
Ohad Schneider

2
@hagen처럼 명령을 실행 한 결과로 기본값을 만드는 방법을 보여 주면이 대답이 더 나을 것입니다 (답은 부적절합니다).
sautedman

309

다음과 같이 변수의 기본값을 설정할 수 있습니다.

somecommand.sh

#!/usr/bin/env bash

ARG1=${1:-foo}
ARG2=${2:-bar}
ARG3=${3:-1}
ARG4=${4:-$(date)}

echo "$ARG1"
echo "$ARG2"
echo "$ARG3"
echo "$ARG4"

작동 방식의 예는 다음과 같습니다.

$ ./somecommand.sh
foo
bar
1
Thu Mar 29 10:03:20 ADT 2018

$ ./somecommand.sh ez
ez
bar
1
Thu Mar 29 10:03:40 ADT 2018

$ ./somecommand.sh able was i
able
was
i
Thu Mar 29 10:03:54 ADT 2018

$ ./somecommand.sh "able was i"
able was i
bar
1
Thu Mar 29 10:04:01 ADT 2018

$ ./somecommand.sh "able was i" super
able was i
super
1
Thu Mar 29 10:04:10 ADT 2018

$ ./somecommand.sh "" "super duper"
foo
super duper
1
Thu Mar 29 10:05:04 ADT 2018

$ ./somecommand.sh "" "super duper" hi you
foo
super duper
hi
you

2
그래. 은 -(는 부정입니까?) 저를 혼동.
Raffi Khatchadourian

5
아니-배쉬가 배정을하는 이상한 방법입니다. 좀 더 명확히하기 위해 몇 가지 예를 추가하겠습니다 ... 고마워!
Brad Parks

44
if [ ! -z $1 ] 
then 
    : # $1 was given
else
    : # $1 was not given
fi

1
기술적으로 빈 문자열 ''을 전달하면 매개 변수로 계산 될 수 있지만 검사에서 누락됩니다. 이 경우 $ #는 얼마나 많은 매개 변수가 주어 졌는지 말할 것입니다
vmpstr

18
-n와 동일합니다 ! -z.
l0b0

나는 다른 결과를 사용하여 얻을 수 -n! -z내가 그 여기 경우가 아니라 말할 것 때문에.
Eliezer

변수를 인용하지 못했기 때문에 [ -n $1 ] 항상 true 입니다. bash를 사용 [[ -n $1 ]]하면 예상대로 동작합니다. 그렇지 않으면 인용해야합니다[ -n "$1" ]
glenn jackman

21

당신은 인수의 수를 확인할 수 있습니다 $#

#!/bin/bash
if [ $# -ge 1 ]
then
    $1
else
    foo
fi

10

변수 $ 1 .. $ n 인 경우 대체를 사용하려면 일반 변수에 기록해야합니다.

#!/bin/bash
NOW=$1
echo  ${NOW:-$(date +"%Y-%m-%d")}

2
위 의 Brad의 대답 은 인수 변수가 중간 변수없이 대체 될 수 있음을 증명합니다.
Vadzim

2
고정 된 값 대신 날짜와 같은 명령을 기본값으로 사용하는 방법에 주목 +1 이 작업을 할 수 있습니다 :DAY=${1:-$(date +%F -d "yesterday")}
가렌 S

3

선택적인 다중 인수의 경우 ls하나 이상의 파일을 사용할 수 있는 명령 과 유사 하거나 기본적으로 현재 디렉토리의 모든 항목을 나열합니다.

if [ $# -ge 1 ]
then
    files="$@"
else
    files=*
fi
for f in $files
do
    echo "found $f"
done

경로에 공백이있는 파일에 대해서는 올바르게 작동하지 않습니다. 그 작업을 아직 수행하는 방법을 찾지 못했습니다.


2

이는 선택적 1 차 인수에 대한 기본값을 허용하고 여러 인수를 유지합니다.

 > cat mosh.sh
   set -- ${1:-xyz} ${@:2:$#} ; echo $*    
 > mosh.sh
   xyz
 > mosh.sh  1 2 3
   1 2 3 

1

변수 대체를 사용하여 고정 값 또는 명령 (예 date:)을 인수 로 대체 할 수 있습니다 . 지금까지 답변은 고정 값에 중점을 두었지만, 이것이 날짜를 선택적 인수로 만드는 데 사용한 것입니다.

~$ sh co.sh
2017-01-05

~$ sh co.sh 2017-01-04
2017-01-04

~$ cat co.sh

DAY=${1:-$(date +%F -d "yesterday")}
echo $DAY
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.