스크립트에서 나는 $0
가능한 상대 경로를 얻는다 . 그것을 절대로 변환하기 위해 이해할 수없는이 솔루션을 찾았습니다.
abspath=$(cd ${0%/*} && echo $PWD/${0##*/})
내 문제는 내부의 마법 ${0%/*}
과 ${0##*/}
. 전자가 dirname을 추출하고 후자가 파일 이름을 추출하는 것처럼 보입니다. 어떻게 얻지 못합니다.
답변
정의 :
${string%substring}
$substring
끝에서 가장 짧은 일치 항목을 삭제합니다 $string
.
${string##substring}
$substring
의 시작 부분에서 가장 긴 일치 항목을 삭제합니다 $string
.
귀하의 예 :
abspath=$(cd ${0%/*} && echo $PWD/${0##*/})
${0%/*}
마지막 슬래시 뒤의 모든 항목을 삭제하여 스크립트의 디렉토리 이름 (상대 경로 일 수 있음)을 제공합니다.
${0##*/}
마지막 슬래시까지 모든 것을 삭제하여 스크립트 이름 만 제공합니다.
따라서이 명령은 스크립트의 디렉토리로 변경되고 현재 작업 디렉토리 (에서 제공 $PWD
)와 스크립트의 이름을 연결하여 절대 경로를 제공합니다.
무슨 일이 일어나고 있는지 보려면 :
echo ${0%/*}
echo ${0##*/}
답변
Shawn은 가장 간단한 해결책을 가지고있었습니다 readlink -f $0
. 이상한 파일 이름을 처리하려면 다음을 사용하십시오.
absolute_path_x="$(readlink -fn -- "$0"; echo x)"
absolute_path="${absolute_path_x%x}"
답변
이 작업을 수행하는보다 안전하고 읽기 쉬운 방법은 다음과 같습니다.
abspath=$(unset CDPATH && cd "$(dirname "$0")" && echo $PWD/$(basename "$0"))
노트:
- 경우
$0
없는 이전 경로 베어 파일 이름입니다, 원래 스크립트가 실패하지만 여기에 주어진 하나가 작동합니다. (문제는$0
아니지만 다른 응용 프로그램에있을 수 있습니다.) - 파일 경로가 실제로 존재하지 않으면 두 가지 방법 중 하나가 실패합니다. (에는 문제가
$0
없지만 다른 응용 프로그램에있을 수 있습니다.) - 는
unset
사용자가 수도있는 경우 반드시CDPATH
설정합니다. - 달리
readlink -f
거나realpath
,이 (예를 들어, 맥 OS X) 유닉스가 아닌 리눅스 버전에서 작동합니다.
답변
Shell Parameter Expansion을 배우려면 here 에서 읽을 수 있지만 Expansion이 항상 좋은 선택은 아닙니다. 이 경우 시스템과 같은 거의 모든 유닉스에는 두 가지 유용한 유틸리티가 있습니다.
basename
dirname
첫 번째는 파일 이름을 추출하고 두 번째는 경로를 추출하므로 $ 0이면 다음과 같이 말하십시오.
dirname $0
그리고 당신은 길을 얻을 것입니다.
건배
답변
bash 내장 pwd를 소개합니다. GNU coreutils 패키지에도 있습니다.
$ sh ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
$0: ./cygdrive/c/cygwin/home/../../../../home/jaroslav/tmp/somewhere.sh
cheeky binary from /home/jaroslav/tmp (/home/jaroslav/tmp)
$ cat /home/jaroslav/tmp/somewhere.sh
abs=$( cd `dirname "$0"` ; pwd -P)
absBin=$( cd `dirname "$0"` ; /bin/pwd -P)
echo \$0: $0
echo cheeky binary from $abs \($absBin\)