누군가 명령줄에 옵션을 구문 분석하는 표준이 있다고 말한 적이 있습니다. 그것은 다음과 같습니다:
./script.sh [options/flags] [command or file]
shift
플래그를 전달할 수 있고 나머지 항목은 를 통해 액세스할 수 있기 때문에 이것이 쉘 스크립트를 구문 분석할 때 작업을 더 쉽게 한다는 것을 알고 있지만 $@ or $*
실제 작성된 표준이 있습니까?
내가 본 대부분의 프로그램은 이 표준을 따르지만 몇 가지 예외가 있습니다. 예를 들어, ls
, ls -l /path
및 ls /path -l
는 ls /path -l /path2
모두 허용됩니다.
답변1
POSIX 기본 정의에는 "실용적인 관례" POSIX 기본 유틸리티의 경우.
기준getopts
유틸리티 금액getopt()
시스템 인터페이스("C 함수")는 쉘 스크립트 또는 C 프로그램에서 명령줄을 구문 분석할 때 지침(위에 링크된 페이지 아래)을 따릅니다. 특히 getopts
(예를 들어):
옵션의 끝에 도달하면
getopts
유틸리티는 0보다 큰 값으로 종료해야 합니다. 쉘 변수는OPTIND
첫 번째 피연산자의 인덱스로 설정되어야 하며,"$#" +1
피연산자가 없는 경우에는 해당 값을name
문자로 설정해야 합니다 . .다음 중 하나는 옵션의 끝을 식별해야 합니다.첫 번째--
인수가 옵션 인수가 아닙니다. 옵션 인수가 아니고 로 시작하지 않는 인수를 찾으면-
오류가 발생합니다.
이것이 기본적으로 말하는 것은 옵션이 먼저 오고 그 뒤에 피연산자("명령 또는 파일")가 와야 한다는 것입니다.
다른 방법으로 이 작업을 수행하면 쓸모없거나 불가능해지며 getopts
명령 getopt()
에 대한 옵션과 피연산자를 지정하는 POSIX 방식에 익숙한 사용자에게 혼란을 줄 수도 있습니다.
위 기준은 POSIX 유틸리티에만 적용되지만 일반적으로 Unix 유틸리티의 우선순위를 설정합니다. 분명히 비표준 Unix 유틸리티는 이를 따를 수도 있고 깨뜨릴 수도 있습니다.
예를 들어, GNU coreutils는 표준 유틸리티를 구현하더라도 다음과 같은 작업을 허용합니다.
$ ls Documents/ -l
POSIXLY_CORRECT
환경 변수가 설정되지 않은 경우 동일한 유틸리티의 BSD 버전이 설정되지 않습니다.
그 결과 다음은 BSD 시스템에서 예상대로 작동합니다(즉, POSIX 동작을 예상하는 경우).
$ touch -- 'test' '-l'
$ ls -l test -l
-rw-r--r-- 1 kk kk 0 Jan 11 16:44 -l
-rw-r--r-- 1 kk kk 0 Jan 11 16:44 test
그러나 GNU coreutils 시스템에서는 다음을 얻습니다.
$ ls -l test -l
-rw-r--r-- 1 kk kk 0 Jan 11 16:44 test
하지만:
$ env POSIXLY_CORRECT=1 ls -l test -l
그리고
$ ls -l -- test -l
또한 GNU 시스템에서는 "올바른" 일을 합니다.
답변2
너무 길어요.
- 하나 있다표준 명령줄 형식.
- 인수 앞에 옵션이 필요합니다.
- 표준의 이 부분은 널리 무시됩니다.
한 가지 예
Python에서 사용한 세 가지 옵션 구문 분석 라이브러리 모두기본분산된 매개변수를 허용하고 공통 콘텐츠에 대한 설명을 제공합니다.
이제 더 이상 사용되지 않는 Python 표준 라이브러리 모듈
optparse
허용하다:OptionParser.enable_interspersed_args()
옵션이 아닌 첫 번째 항목에서 구문 분석이 중지되지 않도록 설정하여 스위치에 명령 인수를 삽입할 수 있습니다. 이것이 기본 동작입니다.
현재 Python 표준 라이브러리 모듈
argparse
확산 매개변수를 허용(및 허용만)합니다.click
, 내가 현재 가장 좋아하는 라이브러리는 다음을 허용합니다.비활성화할 분산 매개변수:click.Context(allow_interspersed_args=False)
그러나 이 가능성은 문제 해결의 고급 섹션에서 논의됩니다.하위 명령에 대한 알 수 없는 매개변수.