PATH에서 프로그램의 전체 경로를 안정적으로 찾는 방법은 무엇입니까? 경로 대신 내장 이름을

PATH쉘 스크립트를 사용하여 주어진 프로그램의 경로를 찾아야합니다 . 경로는 프로그램의 실제 전체 경로 여야하며, 나중에 자체를 exec*검색하지 않는 함수 중 하나로 전달 될 수 있습니다 ( PATH예 🙂 execv.

같은 프로그램이 있습니다 kill실제 프로그램 내장 동시에 쉘로 사용할 수 있습니다. 이 경우 실제 프로그램의 전체 경로가 필요합니다.

POSIX 표준의 2.9.1.1 절 명령 검색 및 실행에PATH 지정된대로 프로그램을 찾을 수있는 여러 유틸리티가 있습니다 .

which표준의 일부가 아닙니다. 일부 시스템에서는 일반 프로그램 일 수 있지만 일부 쉘은 기본 제공 프로그램입니다. 대부분의 시스템과 쉘에서 사용할 수 있지만 내장 버전의 쉘은 실행 파일 경로 대신 내장 이름을 반환합니다. 또한 어떤 식 으로든 표준화되지 않았으며 출력을 반환하고 다른 옵션을 사용할 수 있습니다.

bash# which kill
/usr/bin/kill
dash# which kill
/usr/bin/kill
fish# which kill
/usr/bin/kill
mksh# which kill
/usr/bin/kill
tcsh# which kill
kill: shell built-in command.
zsh# which kill
kill: shell built-in command

whence이는, 내장 된 몇 조개. 그러나 많은 쉘에서는 사용할 수 없습니다. 프로그램 경로 대신 내장 이름을 반환합니다. -p이 동작을 변경하기 위해 A 가 전달 될 수 있습니다.

bash# whence kill
bash: whence: command not found
dash# whence kill
dash: 1: whence: not found
fish# whence kill
fish: Unknown command 'whence'
mksh# whence kill
kill
mksh# whence -p kill
/usr/bin/kill
tcsh# whence kill
whence: Command not found.
zsh# whence kill
kill
zsh# whence -p kill
/usr/bin/kill

commandPOSIX : 2008에 의해 지정된 내장 이 있습니다 . 불행히도 일반 명령과 내장을 검색하고 동일한 이름의 내장으로 음영 처리 된 프로그램 경로 대신 내장 이름을 반환합니다. 일부 오래된 쉘은 아직 구현하지 않았습니다.

bash# command -v kill
kill
dash# command -v kill
kill
fish# command -v kill
/usr/bin/kill
mksh# command -v kill
kill
tcsh# command -v kill
command: Command not found.
zsh# command -v kill
kill


답변

직접 검색하십시오.

export IFS=":"
[ -z "${1}" ] && exit 1
for dir in $PATH
do if [ -x "${dir}/${1}" ]
   then echo "${dir}/${1}"
        exit 0
   fi
done
echo ${1} not found
exit 1

테스트 bash, dash, ksh, mksh,zsh

최신 정보

위의 내용은 독립 실행 형 스크립트에는 적합하지만이 스크립트를 더 큰 스크립트에 포함시키려는 경우 다음과 같은 것을 사용하는 것이 좋습니다.

function find_path() {
   IFS_SAVE="${IFS}"
   export IFS=":"
   [ -z "${1}" ] && exit 1
   for dir in $PATH
   do if [ -x "${dir}/${1}" ]
      then echo "${dir}/${1}"
           export IFS="${IFS_SAVE}"
           return 0
      fi
   done
   export IFS="${IFS_SAVE}"
   echo ${1} not found
   return 1
}

그 때문에입니다 IFS일치, 또한 스와핑 찾은 후 복원 exit의와 return의를