나는 그것이 command 에서 사용되는 것을 보았습니다 --
.compgen
예를 들어:
compgen -W "foo bar baz" -- b
--
저 안에 있는 건 무슨 뜻인가요?
답변1
--
더 정확하게 말하면 대부분의 Bash에서는 이중 대시( )가 사용됩니다.내장명령 및 기타 여러 명령을 사용하여 명령 옵션의 끝을 알리고 그 후에는 위치 인수만 허용됩니다.
사용 예: 파일에서 문자열을 찾고 싶다고 가정해 보겠습니다 -v
. 이 옵션은 일반적 -v
으로 일치의 의미를 반전시키는 것으로 간주되지만(일치하지 않는 행만 표시) --
다음과 같이 문자열을 grep할 수 있습니다.-v
grep -- -v file
답변2
man bash
우리는 읽을 수 있습니다쉘 내장 명령부분(온라인 문서):
달리 명시하지 않는 한, 이 섹션에 설명된 각 내장 명령은 accept 옵션으로
-
시작됩니다 .--
옵션의 끝을 나타냅니다..
:
,true
,false
내장 함수는test
옵션을 허용하지 않으며--
특별히 취급되지 않습니다.exit
,logout
,break
,continue
및let
내장 함수는 가 필요 없이shift
로 시작하는 인수를 허용하고 처리합니다 . 인수를 허용하지만 허용 옵션으로 지정되지 않은 다른 내장 함수는 잘못된 옵션으로 시작하는 인수를 해석하므로 이러한 해석을 방지 해야 합니다 .-
--
-
--
이것이 옵션이 끝났다는 의미는
echo
아닙니다 .--
답변3
이는 매개변수(옵션) 목록의 끝을 표시합니다.
답변4
사용된 명령에서POSIXgetopt()
옵션 및 기타 여러 옵션을 구문 분석하는 API는 --
옵션의 끝을 표시합니다.
존재하다:
rm -f -- -f
첫 번째 -f
는 옵션으로 처리되고 rm
, 두 번째는 삭제할 파일 이름으로 처리됩니다. 그 이후의 모든 항목은 --
옵션으로 간주되지 않기 때문입니다.
POSIX 호환 유틸리티 및 getopt()
구현에서는 옵션이 아닌 인수 뒤에는 옵션이 허용되지 않습니다. 예를 들면 다음과 같습니다.
grep pattern -f
pattern
이라는 파일에서 일치하는 줄을 찾아야 합니다 -f
.
getopt()
그러나 대부분의 GNU 유틸리티(GNU 포함) 와 그 확장(그러나 내장 함수, 심지어 GNU 쉘도 아님) 에서 사용되는 GNU 구현은 환경에 변수가 없는 한 기본적으로 이 작업을 수행하지 않습니다.getopt_long()
grep
bash
bash
POSIXLY_CORRECT
따라서 이를 위해서는 --
옵션이 아닌 주요 인수도 필요합니다.
grep -- pattern -f
옵션의 끝을 표시하는 오래된 방법은 를 사용하는 것입니다 -
. ksh 또는 zsh의 대부분의 구현과 대부분의 내장 기능은 sh
여전히 닫는 태그를 옵션으로 지원한다는 것을 알 수 있습니다. -
그러나 요즘에는 이런 일이 덜 일반적입니다.
--
일부 명령은 후행 옵션 표시를 지원하지 않는 것으로 알려져 있습니다 . 대부분의 echo
구현이 이 범주에 속합니다. 그건임의의 데이터를 출력하는 데 사용할 수 없는 이유 중 하나.
⚠️중요
--
옵션이 아닌 인수가 다음으로 시작하는 경우 -
(또는 일부 명령의 경우 ) +
필요 하지만-
또한 옵션이 아닌 일부 매개변수가 /로 시작 하지 않을 것이라고 보장할 수 없는 경우+
. 포함하다:
rm -f -- "$file"
rm -f -- "${files[@]}"
rm -f -- *.txt
rm -f -- $(command-that-generates-a-list-of-files-or-file-patterns)
cmd | xargs rm -f --
명령이 --
옵션 마커로 끝나는 것을 지원하는지 보장할 수 없는 경우 해당 파일 이름 인수에 대해 대안은 파일 이름 앞에 접두사를 붙이는 것입니다 ./
.
somegrep pattern ./*.txt
이를 추가하지 않으면 --
임의의 명령 주입 취약점이 발생할 수 있습니다., 특히 당신도 그렇다면확장명을 인용하는 것을 잊었습니다.. 예를 들어:
sed -e 's/foo/bar/' *.txt
현재 작업 디렉토리에 reboot
이라는 파일이 있으면 실행됩니다 . 또는 '-es/.*/reboot/e;#.txt'
으로 변경하여 수정했습니다 .sed -e 's/foo/bar/' -- *.txt
sed -e 's/foo/bar/' ./*.txt
다음에도 적용됩니다.
rename 's/foo/bar/' *foo*
일부 변형이 있습니다 rename
. 일부(덜 취약한) rename
변형은 지원되지 않습니다 --
.
print $var
zsh
(인용되지 않은 인수 확장은 이 쉘에서 상대적으로 안전하더라도) 포함된 경우 다시 시작 $var
이 실행됩니다 -va[1$(reboot)]
. 수정되었거나 print -- $var
백 슬래시 처리를 비활성화 print - $var
할 수도 있습니다 print -r -- $var
.