Bash : 첫 번째 명령 줄 인수를 사용하고 나머지는 전달합니다.


82

예:

check_prog hostname.com /bin/check_awesome -c 10 -w 13

check_remote -H $HOSTNAME -C "$ARGS"
#To be expanded as
check_remote -H hostname.com -C "/bin/check_awesome -c 10 -w 13"

위의 내용이 이해되기를 바랍니다. 약 20 개 이상의 명령에 대해 이것을 사용하므로 인수가 변경됩니다. 프로그램을 래핑하는 이상한 방법이지만 여기에서 사용하는 몇 가지 시스템의 몇 가지 문제를 해결합니다 (70 년대의 코드를 좋아합니다).

위의 내용은 perl 또는 python으로 작성할 수 있지만 Bash가 선호되는 방법입니다.

답변:


107

시프트 를 사용할 수 있습니다

shift는 위치 매개 변수에서 작동하는 쉘 내장입니다. shift를 호출 할 때마다 모든 위치 매개 변수를 하나씩 "이동"합니다. $ 2는 $ 1이되고, $ 3은 $ 2가되고, $ 4는 $ 3이됩니다.

예:

$ function foo() { echo $@; shift; echo $@; } 
$ foo 1 2 3
1 2 3
2 3

9
대박! 매력처럼 작동하는 echo $1 shift echo $* 것은 이것을 검색하는 미래의 사람들을 위해 shift를 사용하는 방법의 예입니다. 실행하면 ./script.sh cmd1 cmd2 cmd3 cmd4$ 1이 cmd1로 설정되고 나머지는 cmd2 cmd3 cmd4가됩니다. 내가 원하는대로
user554005

3
그리고 $#이미 0이 아닌 한 1만큼 줄어 듭니다 shift. 숫자 인수를 제공 하여 둘 이상의 위치로 이동할 수도 있습니다 .
Keith Thompson

8
@ user554005 : 당신은 거의 항상 사용해야하는 echo "$@"대신 echo $*또는 echo "$*"인용 부호로 둘러싸이지 않은 형태와 인용하기 때문에 $*형태가 일반적으로 원하지 않는 인수를 "결합".
Dennis Williamson

1
그래서 일반적인 사용은 SOME_VAR=$1; shift; some_cmd "$*". 이제 some_cmdargs 2..n이 전달됩니다. 잘 작동합니다 ... 감사합니다!
Brad Parks

5
@BradParks 파일 이름을 다른 명령에서 읽을 인수로 전달할 때 파일 이름에 공백이 포함되어 있으면 이스케이프 된 공백이 공백 앞에 백 슬래시로 전달되도록 보장 하기 SOME_VAR=$1; shift; some_cmd "$@"때문에 원한다고 생각합니다 "$@". 문자 "$*"를 삭제합니다 \ (또는 위에서 설명한대로 파일 이름을 병합합니다).
modulitos

14

프로그래머로서 저는 shift상태를 수정하는 작업이 스크립트의 많은 부분에 영향을 미치고 이해, 수정 및 디버그를 더 어렵게 만들 수 있기 때문에 반대 할 것을 강력히 권장합니다 . 대신 다음을 사용할 수 있습니다.

#!/usr/bin/env bash

all_args=("$@")
first_arg=$1
second_args=$2
rest_args=("${all_args[@]:2}")

echo "${rest_args[@]}"

3
간단한 문자열 변수에 인수 목록을 저장하거나 큰 따옴표없이 변수를 확장하지 않는 것이 좋습니다 (예 : REST_ARGS여기). 배열 (예 ALL_ARGS:)을 사용 [@]하고 큰 따옴표 와 함께 확장 합니다.
Gordon Davisson

1
@GordonDavisson bash추천으로 스 니펫 을 다시 작성 하거나 다른 스 니펫을 작성할 수 있습니까? 나는 그것을 더 많이 이해하고 bash지금 작업중 인 일부 스크립트 에서 사용하고 싶습니다. 미리 감사 드리며 좋은 일을 계속하십시오!
Abdullah

3
추천 양식을 표시하도록 수정했습니다. 인수 목록을 문자열로 저장하면 여러 인수와 공백을 포함하는 단일 인수를 구분하지 못합니다. 큰 따옴표없이 확장하면 모든 공백 (원래 인수 내에 있던 공백 포함)으로 분할되고 파일 이름 와일드 카드처럼 보이는 모든 항목도 확장됩니다. 예를 들어 원본을으로 실행하면 ./script "foo" "bar" "six * nine""six <list of files in the current directory> nine"이 인쇄됩니다.
Gordon Davisson

2
또한 특별한 의미를 가진 다양한 대문자 이름과의 충돌을 피하기 위해 소문자 또는 대소 문자 혼합 변수 이름을 권장합니다. 아, 그리고 shellcheck.net 은 문제가있는 인용문과 기타 일반적인 실수를 지적하는 데 능숙합니다.
Gordon Davisson

감사합니다 @GordonDavisson 이제 더 나은 BASH 스크립트를 작성할 수 있으며 내 대답을 따르는 사람들은 내 실수를 반복하지 않습니다.
Abdullah
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.