Bash 확장이 "-"로 시작하는 파일을 인수로 전달하지 못하게하려면 어떻게해야합니까?


14

문자열을 재귀 적으로 검색하려고 grep하지만이를 얻습니다.

$ grep -r "stuff" *
grep: unrecognized option '---corporate-discount.csv'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

Bash가 -인수로 시작하는 파일을 전달하지 못하게하려면 어떻게 해야합니까?



3
셸에서 이러한 파일을 전달하지 못하게하고 싶지 않습니까? 문제는 grep옵션이 아니라는 것을 말하는 방법 입니다.
— DonHolgo

11
명확하게 말하면, bash는 어떤 결과가 옵션으로 취급되고 인수로 취급되는지 제어하지 않습니다. 그것은 수신 프로그램의 통제에 있습니다. 예를 들어 subprocess.Popen(['grep', '-r', '-e' 'stuff', '--corporate-discount.csv'])파이썬에서는 어디서나 bash없이 동일한 동작을 얻을 수 있습니다.
— Charles Duffy

1
관련 읽기 : Unix Wildcards* 명령에서 사용하여 발생할 수있는 보안 문제에 대해 Wild Gone Wild . ./*대신 에이 모든 것을 피할 수 있습니다 .
— 와일드 카드

1
@Wildcard, --옵션 끝시길로 사용하는 것도 완벽하게 합리적입니다. POSIX 유틸리티 구문 지침에 따라야합니다. 지침 # 10을 참조하십시오. 물론 모든 프로그램이 POSIX 지침을 따르는 것은 아니지만 문제가되는 프로그램의 작성자를 정리하거나 업계에서 배출하는 것이 정답입니다.
— Charles Duffy

답변:


43

먼저, 대시로 시작하는 인수의 해석은 시작되는 프로그램 grep또는 기타에 달려 있습니다. 쉘은 직접 제어 할 수있는 방법이 없습니다.

grep대부분의 프로그램과 함께 이러한 파일을 처리하고 완전히 무시하지 않는 경우 --옵션의 끝을 나타내는 것으로 인식 하므로

grep -r -e "stuff" -- *

당신이 원하는 것을 할 것입니다. 는 -e경우에 거기 stuff로 시작 -뿐만 아니라.

또는 다음을 사용할 수도 있습니다.

grep -r -e "stuff"  ./*

후자 -는 현재 디렉토리에 호출 된 파일이 있으면 문제를 피할 수 있습니다 . --구분 기호 이후에도 stdin을 의미하는 grep것으로 해석 -되는 반면 현재 디렉토리에서 ./-호출되는 파일 -입니다.


8

Bash 확장이 "-"로 시작하는 파일을 전달하지 못하게 하려면 다음을 사용할 수 있습니다.

echo [!-]*

대부분의 쉘에서 이식 가능하거나 ksh, bash, zsh에만 적용됩니다.

echo !(-*)

예를 들면 다음과 같습니다.이 파일이있는 디렉토리

$ echo *
a b c ---corporate-discount.csv d -e --option.txt

목록 만 표시됩니다 (제공된 extglob경우).

$ shopt -s extglob
$ echo !(-*)
a b c d

$ echo [!-]*
a b c d

그러나 원하는 -옵션으로 grep에게 as 옵션 으로 지정된 파일을 해석하지 않도록 지시하면서 모든 파일을 처리하려면 다음을 추가하십시오 ./.

grep -r "stuff" ./*

정확히라는 어떤 파일이 있다는 보증이있는 경우 또는 -나열된 파일에 존재하지 않는 (GREP은 외로운 해석합니다 -으로 표준 입력에서 읽어 ), 당신은 사용할 수 있습니다 :

grep -r -- "stuff" *

예, GNU 쉘인 bash에 대한 질문이므로 GNU grep이 사용 가능하거나 설치 가능하거나 실제로 사용되고 있다고 가정하는 것이 합리적입니다. @ StéphaneChazelas
— Isaac

그렇습니다. a grep -r -- stuff *는 더 간단하며 비 GNUish greps에서도 작동합니다. 감사합니다. @ StéphaneChazelas
— Isaac

@Isaac 나는 "bash가 가능하다면 GNU grep도 가능하다"라는 합리적인 가정이라고 말하지 않을 것이다. 예를 들어 FreeBSD : bash는 기본적으로 설치되지 않으며 나중에 설치할 수 있지만 grep에는 영향을 미치지 않습니다. GNU grep을 명시 적으로 설치하지 않으면 grep의 BSD 버전으로 유지됩니다. 그러나 그것은 작은 이쑤시개입니다. 나는 extglob을 통한 대체 접근법을 좋아하므로 답을 +1했습니다.
— Sergiy Kolodyazhnyy

2
grepFreeBSD의 @SergiyKolodyazhnyy, AFAIK 는 여전히 GNU를 기반으로 grep하며 옵션이 아닌 옵션 후에 옵션을 인식하는 기능이 여전히 남아 있습니다. OpenBSD와 같은 BSD조차도 grepGNU를 이전 버전의 이식성을 위해 호환 가능 하게 만들었습니다 (여전히 그 동작을 보여줍니다). macOS에서 sh는 bash이지만 $ OSIXLY_CORRECT가 없어도 macOS가 POSIX를 준수한다는 의미에서 grep이 그 동작을 나타내지 않을 것으로 기대합니다. 어쨌든 OP의 grep 은 오류를 제공하기 때문에 GNU와 호환됩니다.
— Stéphane Chazelas

1
참조 echo [!-]*KSH (또는 표준 동등 bash -O extglob의) echo !(-*).
— Stéphane Chazelas 8:19에
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.