매개변수가 -로 시작하는 경우 매개변수를 전송하는 방법

매개변수가 -로 시작하는 경우 매개변수를 전송하는 방법

"-"로 시작하지 않는 매개변수에 도달할 때까지 "-"로 시작하는 모든 매개변수를 제거해야 하는 bash 함수가 있다고 가정해 보겠습니다.

gmx(){

  local options=( );

  while [ "${1:0:1}" == "-"  ]; do
    options+=("${1}")
    shift 1;
  done

  echo "first legit arg: $1"
  "$@" # omg will be executed here, like `omg --rolo`
}

gmx -a -f -c omg --rolo

이것이 효과가 있는 것 같지만 이것이 항상 "omg"를 첫 번째 "법적" 매개변수로 두는 것에 대한 좋은 일반적인 솔루션인지 궁금합니다. 실패할 수 있는 극단적인 경우가 있습니까?

즉, -a, -f, -c는 모두 gmx의 매개변수입니다. 그리고 omg뒤따르는 모든 것은 자식 프로세스에서 실행됩니다.

답변1

공식적이고 가장 좋은 방법은 getopts내장 함수를 사용하여 명령줄 옵션을 구문 분석하지 않는 것입니다.

자세한 내용은 매뉴얼 페이지를 참조하십시오.

참고 사항이 중요할 수 있습니다. bash긴 옵션은 지원되지 않습니다.

긴 옵션을 처리하기 위해 스크립트를 선호하는 경우 이를 지원하는 두 개의 셸이 있습니다: ksh93bosh. 두 쉘 모두 getopt(3)Solaris의 libc 함수가 긴 옵션을 지원하는 것처럼 긴 옵션을 지원합니다 . bosh 매뉴얼 페이지(현재 43페이지부터 시작)를 참조하세요.

http://schilytools.sourceforge.net/man/man1/bosh.1.html

getopts "f:(file)(input-file)o:(output-file)" OPT

-f예를 들어 인수를 사용하고 해당 옵션에 긴 옵션 별칭 --file과 해당 옵션에 대한 두 번째 별칭이 있는 옵션을 지원합니다.--input-file

ksh93도 이를 지원하지만 ksh93 매뉴얼 페이지에는 문서화되어 있지 않습니다.

답변2

while getopts ':' opt; do
    :    # This is where ordinarily a case statement would be,
         # case $opt in ... esac
         # But we use : as a no-op
done

shift "$(( OPTIND - 1 ))"
printf 'arg: %s\n' "$@"

getopts이는 명령줄 옵션을 구문 분석하는 데 사용됩니다 . while첫 번째 비옵션이 발견되면 루프가 종료되고 shift처리된 옵션이 제거되고 $@옵션이 아닌 피연산자만 남습니다 $@.

스크립트

#!/bin/sh

gmx () {
    while getopts ':' opt; do
        :
    done

    shift "$(( OPTIND - 1 ))"
    printf 'arg: %s\n' "$@"
}

gmx -a --foo -c omg lol

출력됩니다

arg: omg
arg: lol

실제 옵션에는 관심이 없으므로 다음과 같은 간단한 루프를 수행할 수 있습니다.

for opt do
    case $opt in
        -*) shift ;;
        *)  break
     esac
done

printf 'arg: %s\n' "$@"

이는 모든 매개변수를 반복하여 대시로 시작하는 각 매개변수를 제거하고 대시로 시작하지 않는 첫 번째 매개변수로 끝납니다.

답변3

방법을 제어할 수 있다면 더 간단한 솔루션GMX--호출되며, 다음과 같이 래퍼의 인수를 래핑된 명령에서 분리하는 데 사용됩니다 .

gmx garg garg garg -- warg warg warg

어디

  • 가르그사용된 매개변수를 나타냅니다.GMX.
  • 와그전송된 매개변수를 나타냅니다.포장지.

편리하게 생략하려면 --선택사항으로 설정하고 "스마트" 검사를 시도하기 전에 검색하면 됩니다.

관련 정보