bash 스크립트의 매개 변수가 문자열과 일치하는지 확인하십시오.


67

bash 스크립트에 전달 된 매개 변수가 문자열과 일치하는지 확인하려는 스크립트를 작성하려고합니다. 내가 지금 설정하는 방법은

if [ "$3" != "-disCopperBld" -a "$4" != "-disCopperBld" -a "$5" != "-disCopperBld" -a "$6" != "-disCopperBld"]

그러나 많은 매개 변수가있을 수 있으므로 더 좋은 방법이 있는지 궁금합니다.

감사

편집 :이 코드 덩어리를 시도하고 옵션 -disableVenusBld와 함께 스크립트를 호출했지만 여전히 "빌드 시작"을 인쇄합니다. 내가 뭔가 잘못하고 있습니까? 미리 감사드립니다!

while [ $# -ne 0 ]
do
    arg="$1"
    case "$arg" in
        -disableVenusBld)
            disableVenusBld=true
            ;;
        -disableCopperBld)
            disableCopperBld=true
            ;;
        -disableTest)
            disableTest=true
            ;;
        -disableUpdate)
            disableUpdate=true
            ;;
        *)
            nothing="true"
            ;;
    esac
    shift
done

if [ "$disableVenusBld" != true ]; then
    echo "Starting build"
fi

답장을 보내 주셔서 감사합니다. 시간을내어 도와 주셔서 감사합니다. 코드 덩어리를 시도했지만 무엇이 잘못되었는지 알 수없는 것 같습니다. 어떤 아이디어? (원래 게시물을 편집하여 코드를 붙여 넣었습니다)
iman453

흠 : 그것은 나를 위해 작동합니다. 나는 #! /bin/sh -당신이 거기에 포함 된 것의 상단에 추가 하고 스크립트를 실행 가능하게 한 다음 ./t.sh"빌드 시작" 을 인쇄하지만 ./t.sh -disableVenusBld아무것도 인쇄하지 않습니다.
Norman Grey

답변:


59

쉘 스크립트에서 옵션 처리를하고있는 것 같습니다. 이에 대한 관용구는 다음과 같습니다.

#! /bin/sh -

# idiomatic parameter and option handling in sh
while test $# -gt 0
do
    case "$1" in
        --opt1) echo "option 1"
            ;;
        --opt2) echo "option 2"
            ;;
        --*) echo "bad option $1"
            ;;
        *) echo "argument $1"
            ;;
    esac
    shift
done

exit 0

(들여 쓰기에 대한 몇 가지 규칙이 ;;있으며 일부 쉘에서는 (--opt1)괄호 일치를 돕기 위해 옵션을 제공 할 수 있지만 이것이 기본 아이디어입니다)


3
shift명령에 대한 인수의 수를 미리 알 수없는 경우 그들이 원하는대로 사용자가 많은 인수를 줄 수있을 때 문은 예를 들어, 사용됩니다. 이러한 경우 인수는 while테스트 조건이 인 루프 에서 처리됩니다 $#. 인수 수가 0보다 크면이 조건이 적용됩니다. $1변수와 shift문 프로세스를 각 인수. 인수가 shift실행될 때마다 인수 수가 줄어들고 결국 0이되어 while루프가 종료됩니다. 출처
Serge Stroobandt

다음은 추가 echo $1 | sed인수 값 처리 와 유사한 예입니다 .
Sroo Stroobandt

26

이것은 나를 위해 일했습니다. 그것은 당신이 요구 한 것을 정확하게하고 더 이상 아무것도하지 않습니다 (옵션 처리 없음). 그것이 좋든 나쁘 든 포스터의 운동입니다 :)

if [[ "$*" == *YOURSTRING* ]]
then
    echo "YES"
else
    echo "NO"
fi

이것은 특수 처리 $* 및 수퍼 테스트 [[]]괄호를 활용합니다.


2
IMHO는 질문이 매개 변수의 존재를 확인하기 만하면되기 때문에 가장 정답이어야했습니다. 나는 변화하지만, 편집 한 $*$@더 - 테스트 할 문자열 그것에 대해 배쉬의 설명서에 대한 공간과 추가 링크를 가질 수 있기 때문에.
h7r

9
= ~ 연산자를 사용 했습니까? 그렇지 않으면 왜 이것이 작동 해야하는지 알지 못하고 정확한 스크립트를 시도해도 실제로 작동하지 않습니다.
Seppo Enarvi

3
작동 안함. bash -c 'echo args=$*; [[ "$@" == "bar" ]] && echo YES || echo NO' -- foo bar
Tobia

2
전체 인수 목록을와 비교합니다 your string. 나는 당신 이이 대답에서 제안한 것을해야한다고 생각합니다 . 즉 : bash -c 'echo args=$*; for i in "$@" ; do [[ $i == "bar" ]] && echo "Is set!" && break ; done' -- bar foo작동합니다.
starfry

2
이 답변은 h7r의 편집이 실패했기 때문에 지난 4 년간 잘못되었습니다. “귀하의 문자열”에 글로브 문자가없고 잘못된 긍정이 포함되어 있으면 원래 답변 (현재 복원)이 작동합니다. 예를 들어, 명령이 create a new certificate이고 "your string"이 cat이면 certificate contains 이기 때문에 일치를보고합니다 cat.
스콧

8

전체 매개 변수 공간을 검색 (와일드 카드 사용)하는 방법은 무엇입니까?

if [[ $@ == *'-disableVenusBld'* ]]
then

편집 : 좋아, 좋아, 그것은 대중적인 대답이 아니었다. 이건 어때, 완벽 해! :

if [[ "${@#-disableVenusBld}" = "$@" ]]
then
    echo "Did not find disableVenusBld"
else
    echo "Found disableVenusBld"
fi

Edit2 : 좋아, 아마 이것은 완벽하지 않을 수도 있습니다 ...- param이 목록의 시작 부분에 있고 -paramXZY 또는 -paramABC와 일치하는 경우에만 작동한다고 생각하십시오. 나는 여전히 bash 문자열 조작으로 원래의 문제를 매우 잘 해결할 수 있다고 생각하지만 여기서는 그렇게 크지 않았습니다 ...


필터링 대체와 전체 대체를 비교하는 두 번째 제안은 합리적으로 작동하며 인수 목록을 방해하지 않는 이점이 있습니다.
Donal Fellows

두 번째 제안 (특히 ${@#)이 무엇을 설명 할 수 있습니까?
velop

1
트윗 담아 가기 여러분은 이것이 $@모든 명령 행 인수를 보유하는 특수 변수 라는 것을 알고 있습니까? 방금 해당 변수에 대해 Bash 문자열 조작을 사용하여 하위 문자열 "-disableVenusBld"를 제거한 다음 원본과 비교했습니다 $@. 따라서 $@equals -foo -bar이면 ${@#-disableVenusBld}여전히 -foo -bar이므로 찾고있는 플래그가 존재하지 않음을 알 수 있습니다. 그러나, $@동일 -foo -disableVenusBld -bar다음 ${@#-disableVenusBld}이 될 것입니다 -foo -bar동일하지 않은 $@, 따라서 내가 찾고 플래그가 있는지 말해! 쿨 어!
Rich

@velop Bash 문자열 조작에 대한 자세한 내용은 여기를 참조하십시오 : tldp.org/LDP/abs/html/string-manipulation.html
Rich

@Rich 꽤 깔끔한 ^^, 설명을 위해 thx.
velop

4
disCopperBld=
for x; do
  if [ "$x" = "-disCopperBld" ]; then disCopperBld=1; break; fi
done
if [ -n "$disCopperBld" ]; then
  ...
fi

에서 시작하는 매개 변수 만 테스트해야하는 경우 $3함수에서 검색하십시오.

## Usage: search_trailing_parameters NEEDLE NUM "$@"
## Search NEEDLE amongst the parameters, skipping $1 through ${$NUM}.
search_trailing_parameters () {
  needle=$1
  shift $(($2 + 2))
  for x; do
    if [ "$x" = "$needle" ]; then return 0; fi
  done
  return 1
}
if search_trailing_parameters -disCopperBld 2 "$@"; then
  ...
fi

그러나 왜 당신이 처음에 이것을하려고하는지 궁금합니다. 일반적인 요구는 아닙니다. 일반적으로 이전 질문에 대한 Dennis의 답변과 같이 옵션을 순서대로 처리 합니다 .

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