실행 파일을 찾을 수 없을 때 "which"의 구현이 "no"를 출력합니까?

실행 파일을 찾을 수 없을 때 "which"의 구현이 "no"를 출력합니까?

내가 읽고있다Bourne 쉘용으로 작성된 Maven 래퍼의 소스 코드. 나는 다음과 같은 내용을 발견했습니다.

if [ -z "$JAVA_HOME" ]; then
    javaExecutable="$(which javac)"
    if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then
# snip

exprarg1and와 함께 사용하면 arg2a는 정규식과 일치합니다 :. 일반적으로 결과는 일치하는 문자의 수입니다. 예를 들면 다음과 같습니다.arg1arg2

$ expr foobar : foo
3

그러나 캡처링 괄호( \(\))를 사용하면 첫 번째 캡처 괄호의 내용이 반환됩니다.

$ expr foobar : '\(foo\)'
foo

여태까지는 그런대로 잘됐다.

위에 인용된 소스의 표현식을 내 컴퓨터에서 평가하면 다음과 같은 결과를 얻습니다.

$ javaExecutable=$(which javac)
$ expr "$javaExecutable" : '\([^ ]*\)'
/usr/bin/javac

존재하지 않는 실행 파일의 경우:

$ nonExistingExecutable=$(which sjdkfjkdsjfs)
$ expr "$nonExistingExecutable" : '\([^ ]*\)'

즉, 존재하지 않는 실행 파일의 경우 출력은 줄바꿈이 포함된 빈 문자열입니다.

which javac소스 코드에서 나를 혼란스럽게 하는 것은 arg1(to)의 출력이 expr문자열을 반환하는 방식입니다 no.

which아무것도 반환 하지 않지만 실행 파일을 찾을 수 없을 때 반환하는 버전이 있습니까?no

그렇지 않다면 이 진술은 항상 참으로 평가될 것이며 이는 이상할 것입니다.

답변1

전통적으로 오류 메시지를 인쇄 하고 성공 상태를 반환하는 whichcsh 스크립트입니다 . no foo in /usr/bin:/bin(적어도 하나의 공통 버전이 있으며 다르게 동작하는 버전도 있을 수 있습니다.) 예FreeBSD 1.0으로 시작(예, 그것은 고대입니다):

    if ( ! $?found ) then
    echo no $arg in $path
    endif

(이 고전적인 구현은 사용자의 를 로드하는 것으로도 악명이 높습니다 .cshrc. 이는 변경되어 PATH잘못된 출력을 유발할 수 있습니다.)

최신 시스템은 일반적으로 C 또는 sh로 작성된 다양한 구현을 가지며 which오류 조건 처리에 대한 최신 표준을 따릅니다. 즉, stdout으로 출력되지 않고 종료 상태가 0이 아닙니다.

답변2

기술적으로 이는 다음 사항을 확인하는 검사입니다.첫번째 단어(또는 공백이 아닌 문자의 첫 번째 시퀀스)를 출력합니다. 그리고 일부 which구현은 침묵하지 않습니다.

  • zshwhich foo표준 foo not found출력 에 쓰기
  • GNU는 stderr which foo에 씁니다 .which: no foo in (<contents of $PATH>)
  • 테스트할 항목은 없지만 이전 Unix 맨페이지에는 "인수 이름이 있는 실행 파일이 경로에서 발견되지 않으면 진단 정보를 인쇄합니다"라는 문구가 있습니다. 표준 오류).

인쇄물이 로 시작하는 특정 변형이 무엇인지는 모르지만 noGNU는 which이 변형에서 영감을 받았거나 영감을 받았을 수 있습니다.

관련 정보