쉘 와일드 카드 문자 확장을 중지 하시겠습니까?


88

컴파일 된 명령 줄 프로그램이 bash 또는 csh에 매개 변수의 와일드 카드 문자를 확장하지 않기를 원한다고 알리는 방법이 있습니까?

예를 들어 다음과 같은 쉘 명령이 필요할 수 있습니다.

foo *

해당 문자의 숫자 ASCII 값을 간단히 반환합니다.

답변:


119

아니요. 명령이 실제로 실행되기 전에 확장이 발생합니다.
명령을 실행하거나 별표를 인용하여 glob을 비활성화 할 수 있습니다.

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

$ # or disable the glob (noglob)
$ set -f
$ foo *

$ # alternative to set -f
$ set -o noglob
$ # undo it by 
$ set +o noglob

3
또한 확장 할 것이 없으면 확장이 없습니다. 빈과 즉 pwd, echo *그냥*
샘 boosalis

7
@sam 이것은 실제로 옵션 설정 방법에 따라 다릅니다. tldp에서 : "일치하는 파일 이름이없고 쉘 옵션 nullglob이 비활성화 된 경우 단어는 변경되지 않은 상태로 유지됩니다. nullglob옵션이 설정되어 있고 일치하는 항목이 없으면 단어가 제거됩니다."
Chris Middleton

고마워요, 그게 이해가 아닌 관찰에서 나온 것임을 인정 했어야 했어요.
sam boosalis

@ c00kiemon5ter 실행 취소하는 방법 set -f? 그렇 unset -f습니까?
Nam G VU

1
@NamGVUset +f
Yngvar Kristiansen

62

명령 자체가 globbing을 끌 수는 없지만 사용자가 특정 명령을 glob하지 않도록 Unix 셸에 지시 할 수 있습니다. 이것은 일반적으로 쉘의 구성 파일을 편집하여 수행됩니다. foo명령 경로를 따라 명령을 찾을 수 있다고 가정하면 적절한 구성 파일에 다음을 추가해야합니다.

sh, bash 및 ksh 쉘의 경우 :

alias foo='set -f;foo';foo(){ command foo "$@";set +f;}

csh 및 tcsh 쉘의 경우 :

alias foo 'set noglob;\foo \!*;unset noglob'

zsh 셸의 경우 :

alias foo='noglob foo'

명령 경로를 사용할 필요는 없습니다. foo 명령이 ~ / bin 디렉토리에 저장되어 있다고 가정하면 위의 내용은 다음과 같습니다.

sh, bash 및 ksh 쉘의 경우 :

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}

csh 및 tcsh 쉘의 경우 :

alias foo 'set noglob;$home/bin/foo \!*;unset noglob'

zsh 셸의 경우 :

alias foo='noglob ~/bin/foo'

위의 모든 것은 Apple의 OSX 10.9.2를 사용하여 테스트되었습니다. 참고 : 위 코드를 복사 할 때 공백을 삭제하지 않도록주의하십시오. 중요 할 수 있습니다.

최신 정보:

사용자 geira 는 bash 쉘의 경우

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}

대체 될 수있다

reset_expansion(){ CMD="$1";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'

함수 foo가 필요하지 않습니다.

이 문서를 만드는 데 사용 된 일부 웹 사이트 :


3
이것은 OP가 원하는 것을 실제로 할 수 있음을 증명하기 때문에 받아 들여진 대답이어야합니다. : 일부 bash는 더 나은 방법이 링크 문서 다양한 옵션에 대한 blog.edwards-research.com/2011/05/preventing-globbing
게이라

@geira : 때로는 더 나은 답변이 게시되기 전에 답변이 수락됩니다. 나는 이것이 그러한 경우 중 하나라고 생각합니다. 또한 사용자가 가장 유용하다고 생각하는 답변이 가장 먼저 나온다고 생각합니다. 참고 : 내 답변에 귀하의 의견을 추가했습니다.
David Anderson

@geira, OP는 컴파일 된 프로그램이 쉘과 통신하기를 원합니다. 명령별로 원하는대로 동작하도록 셸을 구성 할 수 있다고 대답하는 것은 유용한 대답이며 나도이 대답을 받아 들일 것이지만 전적으로 정확한지 여부에 대해서는 동의하지 않을 여지가 있습니다.
Charles Duffy

있다는 사실이 반드시해야 한다는 의미는 아닙니다 . 선택 명령에 대한 사용자의 합리적인 기대에서 쉘의 동작이 변경되는 것은 놀랍고 궁극적으로 바람직하지 않은 것처럼 들립니다.
tripleee jul.

@tripleee : 사람들이 릴레이와 진공관을 기대했던 때가있었습니다. 골판지 카드와 종이 테이프에 구멍이 뚫린 것으로 예상되었습니다. 사람들은 계산기와 전화 대신 슬라이드 규칙을 사용했습니다. 나는 이것이 바람직하다고 생각합니다. 나는 그 시간을별로 신경 쓰지 않았다. 나는 다음을 보는 것을 즐긴다.
데이비드 앤더슨

8

확장은 프로그램이 실행되기 전에 쉘에 의해 수행됩니다. 귀하의 프로그램은 확장이 발생했는지 여부에 대한 단서가 없습니다.

   set -o noglob

호출하는 셸에서 확장을 끄지 만 프로그램을 호출 하기 전에 해야합니다.

대안은 당신의 주장을 인용하는 것입니다.

foo "*"

4
setopt는 zsh 특정 명령으로 보입니다. 다른 포스터가 말했듯이 bash의 경우 set -o noglob와일드 카드 확장을 비활성화 하는 데 사용합니다.
Wirawan Purwanto

이제 수정되었습니다. 감사합니다
Brian Agnew

1

주의 : 마스크와 일치하는 이름이 없으면 bash는 확장없이 인수를 그대로 전달합니다!

Proof (pa.py는 인수를 인쇄하는 매우 간단한 스크립트입니다) :

 $ ls
f1.cc  f2.cc  pa.py
 $ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
 $ ./pa.py *.cpp
['./pa.py', '*.cpp']

3
항상 그런 것은 아닙니다. set -o nullglob또는 shopt -s failglob이 동작이 변경됩니다 (매우 다른 두 가지 방식).
Charles Duffy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.