"/ bin / ["은 정확히 어떻게 작동합니까?


50

나는 항상 폴더 /bin[프로그램 이 있다는 것에 놀랐습니다 .

이것이 우리가 다음과 같은 일을 할 때 호출되는 것 if [ something ]입니까?

[쉘에서 프로그램을 명시 적으로 호출하면 해당을 요청 ]하고 닫는 괄호를 제공하면 괄호 사이에 삽입 한 내용에 관계없이 아무것도하지 않는 것 같습니다.

말할 필요도없이, 즉도 작동하지 않는 프로그램에 대한 도움말보기에 대한 일반적인 방법으로 man [[ --help작동합니다.


11
@IporSircer [test하지 말고 명령을 나타내 expr므로 다음과 같아야합니다.man test
Sergiy Kolodyazhnyy

8
man '['나를 위해 잘 작동합니다- [당신이 인용하는 것을 잊었 거나 "works"의 다른 정의를 가지고 있습니다.
Toby Speight

3
몇 가지 경고 : [인수를 평가하므로 모든 인수 사이에 공백이 있어야합니다. [ a=b ]비교가 아닙니다 : 항상 참입니다 (단일 문자열 : "a = b", 항상 참으로 평가됩니다 ). 그리고 인수는 4 개로 제한해야합니다 (최근의 구현에서는 더 많은 것을 허용하지만). 예를 들면 : [ "a" = "b" ]"a" "=" "b"와 불필요한 테스트 종료 인수 : "]")가 이미 4 개로 제한되어 있습니다. 더 필요한 경우 : 예를 들어 다음과 같은 체인 테스트 :if [ "$Var_a" = "foo" ] && [ "$Var_b" = "bar" ] ; then : do something ; fi
Olivier Dulac

1
@OlivierDulac !자체는 (이스케이프되지 않고 인용되지 않은) 대체되지 않으며 훨씬 좋습니다 if ! [ .... 사용하는 모든 배쉬 확장 !은 적어도 다른 캐릭터를 포함합니다
muru

3
또한 [내장 된 bash(및 아마도 다른 쉘도) 있으며, 대신에 사용될 수 있습니다 /bin/[. 또한 test많은 시스템 에는 -link 가 있으며 , /bin/[그 반대의 경우도 마찬가지입니다. 그러나 다른 시스템에는 별도의 명령이 있습니다.
Baard Kopperud

답변:


63

[명령의 임무는 테스트 표현식을 평가하는 것입니다. 표현식이 true로 해석되면 0 종료 상태 (즉, true )로 리턴하고 그렇지 않으면 false로 리턴됩니다 .

그것은 아무것도하지 않는 것이 아니라 결과가 종료 상태에서 발견된다는 것입니다. 쉘에서는 $?Bourne과 같은 쉘 또는 $status대부분의 다른 쉘 (fish / rc / es / csh / tcsh ...) 에서 마지막 명령의 종료 상태를 확인할 수 있습니다 .

$ [ a = a ]
$ echo "$?"
0
$ [ a = b ]
$ echo "$?"
1

와 같은 다른 언어에서는 perl종료 상태가 예를 들어 반환 값으로 반환됩니다 system().

$ perl -le 'print system("[", "a", "=", "a", "]")'
0

모든 현대적인 Bourne과 같은 쉘 (및 fish)에는 내장 [명령이 있습니다. 한 /bin다른 쉘을 사용할 때 일반적으로 만 실행됩니다 또는 당신이 좋아하는 일을 할 때 env [ foo = bar ]find . -exec [ -f {} ] \; -print또는 그 perl위의 명령 ...

[명령은 test이름으로 도 알려져 있습니다. 로 호출되면 test닫기 ]인수가 필요하지 않습니다 .

시스템에 대한 매뉴얼 페이지가 없을 수도 있지만 [아마도 매뉴얼 페이지가 있을 것입니다 test. 그러나 다시, /bin/[또는 /bin/test구현을 문서화한다는 점에 유의하십시오 . [쉘에 내장되어있는 것에 대해 알고 싶다면 , 쉘에 대한 문서를 읽어야합니다.

해당 유틸리티의 히스토리와 [[...]]ksh 테스트 표현식 의 차이점에 대한 자세한 정보는 여기 에서 다른 Q & A를 참조하십시오 .


평소와 같이 좋습니다. @Bregalad 질문 아래에 추가 한 의견에 추가하고 싶습니까? 아니면 여분의 것들? 그렇게하면 "정확하게 작동하는 방법"에 대한 답변이 훨씬 더 완전 해집니다 (^^). "^"보다 더 정확한 정보를 이미 제공했습니다. ^^)
Olivier Dulac

“모든 Bourne과 같은 껍질 (및 물고기)에는 [명령이 내장되어 있습니다.] 21 세기에 실제로는 사실이지만 [. 그것이 Bourne 변종이거나 골동품 버전의 재인지 기억이 나지 않습니다.
Gilles 'SO- 악의를 멈추십시오'

Bourne 쉘이 모두 구현 @Gilles [test유닉스 시스템 III와 내장 명령한다. 그 전에, 거기에 어떤을 없었다 [test단지 외부 binary 명령했다.
jlliagre

@Gilles, 원래 재는 테스트 내장 (expr과 병합)되었지만 선택적으로 . in-ulm.de/~mascheck/various/ash 에 따르면 BSD에는 약 2000 년까지 내장 테스트가 없었습니다. "modern"을 추가했습니다.
Stéphane Chazelas

왜 세상에서하고 싶 find . -exec [ f {} ] \; -print습니까? 명령 find . -type f -print은 훨씬 더 효율적으로 같은 일을 것입니다 ...
이것은 내 진짜 이름이 아닙니다

41

나는 항상 폴더 /bin[프로그램 이 있다는 것에 놀랐습니다 .

당신은 놀랄 권리입니다. null 유틸리티 ( :)를 사용하는 명령 파일 허용 문자 규칙 (휴대용 파일 이름 문자 집합)을 따르지 않는 드문 POSIX 명령 중 하나입니다 .

우리가 다음과 같은 일을 할 때 부름이 무엇 if [ something ]입니까?

정확하게 그러나 if너무 없이도 사용할 수 있습니다 .

[쉘에서 프로그램을 명시 적으로 호출하면 해당을 요청 ]하고 닫는 괄호를 제공하면 괄호 사이에 삽입 한 내용에 관계없이 아무것도하지 않는 것 같습니다.

그것은 보이지 않지만 실제로는와 함께 사용될 때와 똑같은 일을합니다 if. 즉, 괄호 안에 넣은 것에 따라 종료 상태를 0 (true) 또는 다른 것 (false)으로 설정합니다. (이유로) test명령 과 동일한 동작입니다 . 유일한 차이점은 결말을 찾는 것입니다 ]. 자세한 내용 man test을 참조하십시오.

말할 필요도없이, 즉도 작동하지 않는 프로그램에 대한 도움말보기에 대한 일반적인 방법으로 man [[ --help작동합니다.

운영 체제에 따라 다릅니다. man [몇 가지 주류 Gnu / Linux 배포판에서 확실히 작동하지만 Solaris에서는 그렇지 않습니다.

[ --help어쨌든 구문을 깨고 엔딩이 누락되어 구현에 따라 작동하거나 작동하지 않을 수 있습니다 ]. 또한, 에 대한 POSIX 표준 test/ [명령은 명시 적으로 포함하여 모든 옵션을 배제 --그래서 모두 옵션을 종료 [ --help ]하고 test --help반환해야 true하고 디자인에 의해 침묵을. 괄호 안에 넣거나 그 뒤에 넣은 [옵션 (예 : -f file, -n string등)은 옵션이 아니라 피연산자 입니다.

모든 현대적인 Bourne 스타일 쉘 인터프리터 (예 bash: ksh, dashzsh일부는)는 test/ [유틸리티를 내부적으로 내장형으로 구현 하므로이를 사용할 때 참조 할 올바른 매뉴얼 페이지는 쉘이 아닌 쉘 중 하나 일 수 있습니다 test.

Unix System III (1981) 이전에 Bourne 쉘은 test유틸리티를 내장으로 구현하지 않았 으므로 외부 바이너리 명령 구현 만 사용할 수있었습니다. 중 하나 없었다 [유닉스 버전 7에서 예를 들어 사용자가 입력했다, 그래서 명령은 유닉스 시스템 III까지 (내부 또는 내장) :

if test something ; then

대신에:

if [ something ] ; then


흠 ..를 CentOS는 (일반적으로 인정 하듯이 6.8 여전히) 충분히 명확하게 주류 아니다 "남자는 [확실히 주류 GNU / 리눅스 배포판에 나를 위해 작동":) man test작동하지만 man [ 다른 한편으로 내 Cygwin에서 환경에 대해 알려진 않습니다 man [!
Adam

1
@Adam 네, 맞습니다. 모든 주류 Linux 배포판을 작성하지는 않았지만 그것이 나를 위해 효과가 있다고 생각했습니다 (예 : 테스트 한 것). OL 7.2 (RHEL 7.2) 클론과 Mint 17.1 (Ubuntu 14.04)입니다.
jlliagre

man [Manjaro (Arch Linux 기반)에서는 작동하지 않는 것 같습니다. 에 대한 매뉴얼 test목록 [ --help도움말을 보여 주지만, 흥미롭게도 그렇지, 대신 누락에 대해 불평한다 유효한 호출과 ]와 같은, --version. 를 추가 ]해도 아무런 효과가 없으므로 from 이외의 도움을받는 것은 불가능합니다 man test.
Darkhogg

@Darkhogg 당신이 시도 할 수 /usr/bin/[ --help또는 /bin/[ --help.
jlliagre

1
@jlliagre 당신은 완전히 맞습니다, 나는 내장을 사용하고있었습니다. env [ --help뿐만 아니라 /usr/bin/[ --help(I 인용 할 필요가 있지만, 완전히 좋은 일 /usr/bin/[이나 zsh을 불평).
Darkhogg

10

[실제로는 일반적으로 test명령이라고합니다. 이 명령의 일반적인 사용은 단순히 표현식을 평가하고 해당 조건 (true 또는 false)을 리턴하는 것입니다. if-then-else-fi명령문 외부에서 if&&이나 ||연산자 를 통해 다른 명령을 조건부로 실행하기 위해 사용할 수 있지만 명령문 에서 자주 사용됩니다 .

$ [ -e /etc/passwd  ] && echo "File exists"
File exists

$ test -e /etc/passwd && echo "File exists"
File exists

보다 구체적으로, 평가는 종료 상태를 통해 다른 명령과 통신됩니다. 일부 프로그램은 다른 유형의 이벤트 (프로그램 완료, 실행 중 발생하는 특정 유형의 오류 또는 구문 오류)를 나타 내기 위해 종료 상태를 출력하도록 선택할 수 있습니다. test명령 의 경우 0true를 1나타내며 false를 나타냅니다. Stephan이 지적했듯이 구문 오류는 종료 상태를 생성 2합니다.

위치는 시스템에 따라 다르며, 언제 맨 페이지가 표시되지 않았는지 설명합니다 man [. 예를 들어 FreeBSD에서는 아래에 /bin있습니다. Linux (또는 내 경우에는 Ubuntu 16.04)의 위치는입니다 /usr/bin/. 당신이 할 경우 man [또는 man testLinux 시스템에서, 당신은 동일한 문서를 열어 볼 수 있습니다. 또한 쉘에 자체 구현이있을 수 있습니다 test.

또한이 명령을 가지고 있음을 주목해야한다 문제 Korn 쉘의 구현 (일반적으로 알려진, "조건식" 이중 대괄호 참조, [[ "$USER" = "root" ]]해결하기 위해 노력을). 또한 다른 쉘에 의해 사용이 기능 bashzsh.


/usr/bin/Amazon Linux도 마찬가지입니다.
franklinsijo

@ StéphaneChazelas 감사합니다. 답변에 따라 편집 됨
Sergiy Kolodyazhnyy

3

나도 작동 하지 man [않습니다[ --help

일부 배포판 (예 : 우분투)에서는에 man [대한 심볼릭 링크를 따릅니다 test(1). 다른 사람 (예 : 아치)에서는 그렇지 않습니다. (하지만 test매뉴얼 페이지는 문서 사용법도 문서화합니다 [)


type -a [ 쉘 내장 파일과 실행 파일이 모두 있음을 보여줍니다.

$ type -a [
[ is a shell builtin
[ is /usr/bin/[

bash-builtin [ --help은 오류 메시지를 인쇄합니다. (하지만 내장되어 있기 때문에을 사용 help [하거나 bash 매뉴얼 페이지 / 문서를 볼 수 있습니다 ).

/usr/bin/[ --help 다음으로 시작하는 전체 도움말 출력 (GNU Coreutils 버전의 경우)을 인쇄합니다.

$ /usr/bin/[ --help
Usage: test EXPRESSION
  or:  test
  or:  [ EXPRESSION ]
  or:  [ ]
  or:  [ OPTION
Exit with the status determined by EXPRESSION.

      --help     display this help and exit
      --version  output version information and exit

그런 다음 EXPRESSION에 허용되는 구문을 설명합니다.

이것은 당신이를 발견 할 수있는 또 다른 방법이다 [test동일합니다.


BTW, bash 용 프로그래밍 (또는 대화식으로 한 줄짜리 작성) 인 경우 [[대신을 권장 합니다 [. 여러 가지면 더 좋습니다. Serg의 답변에있는 링크를 참조하십시오.


2

[인수에 포함 된 표현식이 true로 간주되면 명령은 종료 상태 0을 리턴하고 인수에 포함 된 표현식이 false로 간주되면 0이 아닌 종료 상태를 리턴합니다. 또한 마지막 인수가 아닌 경우 오류 메시지와 함께 실패합니다 ](순전히 미학적 이유로 수행됨).

예 :

[ hello ]
echo "Exit-status of [ hello ] is:" $?
[ abc = abc ]
echo "Exit-status of [ abc = abc ] is:" $?
[ ]
echo "Exit-status of [ ] is:" $?
[ abc = def ]
echo "Exit-status of [ abc = def ] is:" $?

… 출력합니다 :

[hello]의 종료 상태는 다음과 같습니다. 0       — 비어 있지 않은 문자열이 참으로 간주되기 때문에 
[abc = abc]의 종료 상태는 다음과 같습니다. 0   — 'abc'는 실제로 'abc'와 동일하기 때문에 
[]  종료 상태는 [] : 1             — 빈 문자열이 잘못된 것으로 간주되기 때문에 
[abc = def]의 종료 상태는 다음과 같습니다. 1   — 'abc'가 실제로 'def'와 다르기 때문에

그러나 bash는 많은 다른 쉘은 정말 일반적으로 호출하지 않는 /bin/[(또는 /usr/bin/[) 이러한 경우에 만 (순수 성능상의 이유로) 대신에 정확히 같은 행동을 내장 명령을 호출합니다. /bin/[쉘 내장 대리가 아닌 호출하려면 경로를 명시 적으로 지정하거나 (예 : ☺에는 dirname /bin/[ hello ]접두어 ] 지정할 필요가 없음 ) 내장 대리를 사용하지 않도록 쉘을 구성해야합니다 (예 : enable -n [bash에서).

추신 : 다른 답변에서 말했듯 [이와 관련이 test있습니다. 그러나 test, 달리 마지막 인수로 [필요하지 않습니다 (그리고 전혀 기대하지 않습니다. 인수에 추가 하면 오류 메시지와 함께 실패하거나 잘못된 결과를 반환 할 수 있습니다) . 같은 파일을 해결할 수 있습니다 (예를 들어, 하나는 심볼릭 링크 ,이 경우 동작의 전환은 아마에 의해 구현되는 현재라는 명령을 분석/ 코드 자체) 또는 다른 파일에. 경우 경로가 명시 적으로 지정 되거나 ( ) 그렇지 않은 경우 ( ) 쉘은 일반적으로 내장 된 대리자를 호출합니다 (]]test/bin/test/bin/[test[test/bin/testenable -n test).

PPS : 달리 test하고 [, 현대는 if실제 파일 적이 없다. 쉘 (예 : bash) 구문의 일부입니다 ( if commandA; then commandB; fi세미콜론 대신 줄 바꿈을 사용할 수 있음) . 제로 상태로 종료 된 commandB경우에만 실행됩니다 commandA. 이것은 testor의 동작에 완벽하게 맞아서 [그것들을 if [ "$a" = foo ]; then …; fi (또는 if test "$a" = foo; then …; fi– 읽기 쉽지 않은) 결합 할 수 있습니다 . 그러나 최신 스크립트는 종종 또는 [[대신에 사용 되는데, 이는 (로 ) 실제 파일은 아니지만 항상 셸 구문의 일부입니다.test[if

PPPS : 파일 시스템의 모든 명령에 대한 기사를 man기대하지 마십시오 man. 일부 (심지어 "진짜", 파일 기반) 명령에 대한 정보 (즉, 당신이 가장 확실하게에 대한 정보를 찾을 수있을 것이다 장소뿐만 아니라 특정 쉘 전용 기사에서 어쩌면 현재 일부 쉘 내장 기능에 대한 정보, 누락 될 수 있습니다 test, [, if, [[). 여전히 많은 배포판에는 및에 man대한 명시 적 기사가 있습니다. (에 관해서 는 명백한 이유로 인식되지 않습니다 : 일부 배포판 (닫기없이 )에서 여전히 조용히 처리해야 하지만 일부는 그렇지 않습니다.)test[--helptesta=--help; test "$a"[ --help]


3
그 주 if유닉스 V6에 명령까지했다. Unix V7 (1979)에는 Bourne 쉘 ( if-then-else-fi구문 포함)과 새로운 test명령이 함께 제공되었습니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.