/usr/bin/ "which: no ls in ((null))"이라는 신비한 오류를 반환합니다.

/usr/bin/ "which: no ls in ((null))"이라는 신비한 오류를 반환합니다.

저는 간단한 쉘 프로그램을 작성하고 있습니다. Mac osx 및 ubuntu의 쉘에서 /usr/bin/which를 사용하면 제대로 작동합니다. Red Hat Enterprise Linux 클라이언트 버전 6.3(San Diego)에서 똑같은 명령을 사용하면 "which: no ANYCOMMANDHERE in ((null))" 오류가 발생합니다.

이것 뒤에 어떤 직관이 있습니까? 오류가 무엇을 의미하는지조차 찾을 수 없습니다(내 소스를 표시하면 도움이 될지 알려주세요).

편집: 내 경로는 (셸 내부에서) 다음과 같습니다.

$ echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin

고마워요, 존

답변1

문자열은 해당 인수가 NULL 포인터인 경우 printf의 (문자열) 변환 지정자 (null)에 대한 인수로 일부 C 라이브러리로 대체됩니다.%s

 char *path = 0; /* This would normally be = getenv("PATH"). */
 printf ("which: no foobar in (%s)\n", path);

PATH 환경 변수가 설정되지 않았거나 내보내지지 않은 것 같습니다. 이러한 경우에는 getenv("PATH")0을 반환합니다 . 마지막 가능성은 which유틸리티에 심각한 버그가 있을 수 있다는 것입니다.

잘 작동한다고 말하면 export PATH?

답변2

실제로 여기 있는 다른 모든 사람들이 답변한 질문인 PATH가 설정되지 않았습니다. 어떤 면에서는 맞지만 다른 면에서는 잘못되었습니다.

나는 같은 문제가있었습니다 (bash 사용). Bash "기능"이 누락된 기능인 것 같습니다. Bash는 쉘 변수(환경 변수가 아님!) PATH를 생성한 다음 조회에 사용합니다.

문제는 다음과 같습니다. PATH라는 쉘 변수가 있습니다. 그러나 이것은 환경 변수가 아닙니다. 이는 새로 생성된 하위 프로세스로 내보내지지 않음을 의미합니다. 여기서 우리가 배워야 할 한 가지는 echo $PATH를 사용하면환경변수 PATH가 설정되었습니다. set | grep "^PATH="와 동일한 문제가 있지만 한 가지 방법은 다음을 사용하는 것입니다.외부명령 환경: grep "^path="

셸 세션 예:

$ env -i bash
# A new shell is started with empty environment.
# What follows happens in this new shell:
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ set | grep "^PATH="
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ env | grep "^PATH="
$ which ls
which: no ls in ((null))
$ export PATH
$ env | grep "^PATH="
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ which ls
/bin/ls

달성하려는 목표에 따라 쉘에 로그인 쉘 역할을 하도록 요청할 수 있습니다. bash의 경우 -l입니다. 이런 식으로 /etc/profile 및 기타 파일은 기본적으로 PATH를 올바르게 설정하는 소스입니다.

$ env -i bash -l
$ which ls
/bin/ls

또 다른 방법은 PATH를 내보내는 것입니다(위 참조).

답변3

tcsh에서 동일한 출력을 재현할 수 있습니다.

env -u PATH which ls
which: no ls in ((null))

csh와 tcsh에서는 환경 변수(모든 프로세스에 공통)와 쉘 변수(현재 쉘 호출에 로컬)가 구별됩니다. 두 가지를 모두 참조하기 위해 동일한 구문을 사용합니다(예: ) $PATH. 동일한 이름의 쉘 변수와 환경 변수가 있는 경우 $PATH쉘 변수가 인용됩니다.

[t]csh는 다른 구문을 사용하여놓다쉘 및 환경 변수:

set shell_var = foo
setenv env_var bar

(Bash와 같은 Bourne 기반 쉘은 구문과 용어가 다릅니다. 환경 변수는 "내보낸" 쉘 변수이거나 호출 프로세스에서 상속된 쉘 변수입니다.)

설명하는 증상에 따르면 쉘 변수 $PATH(쓸모 없음)는 있지만 이름이 같은 환경 변수는 없습니다. 이런 일은 일반적으로 일어나서는 안 됩니다. .cshrc.tcshrc/또는 파일 .login에 설정된 명령문을 확인하세요 $PATH.

다음과 같이 당면한 문제를 해결할 수 있어야 합니다.

setenv PATH "$PATH"   # set the environment variable
unset PATH            # unset the shell variable, just to avoid confusion

unset PATH(모든 것이 제대로 작동하는지 확인할 때까지 이 작업을 수행하지 마십시오.)

약간의 재미를 더하기 위해 [t]csh에는 특별한 기능이 있습니다.껍데기변수 $path(소문자 참고). 해당 값은 환경 변수 :의 구분된 구성 요소 배열 입니다 $PATH. 하나를 설정하면 다른 하나가 자동으로 업데이트됩니다.

 setenv PATH /usr/bin:/bin # sets $path to ( /usr/bin /bin )
 set path = ( /usr/local/bin $path ) # sets $PATH to '/usr/local/bin:/usr/bin:/bin'

이는 편리할 수 있지만 원하는 경우 무시 $path하고 처리 할 수 있습니다. 동일한 이름의 쓸모 없는 쉘 변수가 아닌 환경 변수 ( 를 사용하여 ) $PATH를 설정했는지 확인하십시오 .$PATHsetenv

답변4

이 문제는 Redhat 및 포크 메커니즘에만 해당되는 것으로 나타났습니다. 하위 프로세스에는 ubuntu 및 mac osx와 마찬가지로 기본 환경 변수가 제공되지 않습니다. 이는 명시적으로 envp를 부모의 envp로 설정해야 함을 의미합니다(execve 호출에서).

내 질문에 오해의 소지가 있는 표현에 대해 사과드립니다(비록 이러한 유형의 것들을 정확히 찾아내기는 어렵지만).

당신의 도움을 주셔서 감사합니다! 존

관련 정보