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.