스크립트가 호출되는 디렉토리로 변경하는 가장 안전한(또는 가장 우아하거나 가장 짧은) 방법은 무엇입니까?

스크립트가 호출되는 디렉토리로 변경하는 가장 안전한(또는 가장 우아하거나 가장 짧은) 방법은 무엇입니까?

스크립트가 호출되는 디렉토리로 변경하는 안전하거나 Unix 호환 방법이 무엇인지 알고 싶습니다.

두 방법 모두 따옴표 없이 공백과 특수 문자가 포함된 디렉터리에서도 작동합니다. 그러나 어떤 경우에는 이것이 작동하지 않을 수 있습니다. 아니면 있습니까?

#!/bin/bash

cd $(dirname $0)
pwd
cd ${0%/*}
pwd

~/test 1"\ ü`\($$ ./cd.sh
/home/syss/test 1"\ ü`\($
/home/syss/test 1"\ ü`\($

답변1

이는 $0상대 경로일 수 있으므로 cd두 번 호출하면 작동하지 않을 수 있습니다. 또한 $0프로젝트의 디렉터리 부분을 추출합니다.최대사례.최대같지 않음모두. 실패할 수 있는 일부 상황은 다음과 같습니다.

  • 스크립트는 해당 경로를 실행하여 호출되는 것이 아니라 해당 경로에서 셸을 호출 bash myscript(예: find 수행 PATH)하여 호출됩니다.
  • 실행 중에 스크립트가 이동합니다.

스크립트를 헛소리 없이 호출해야 한다는 점을 문서화한 경우 디렉토리 섹션을 사용할 수 있습니다 $0.

$0빈 항목을 통해 발견되거나 PATH일부 셸의 경우에는 주의해야 합니다 PATH. .이 경우는 지원받을 가치가 있으므로 예방 조치를 취해야 합니다 ${0%/*}.

dirname접근 방식도 완전히 간단하지는 않습니다. 명령 대체는 끝에 개행 문자를 먹습니다. 두 가지 방법 중 하나를 사용하는 경우 문자열이 -옵션으로 시작하고 해석될 수 있다는 점에 유의해야 합니다. 패스는 --명령의 옵션 목록을 종료합니다.

case "$0" in
  */*) cd -- "${0%/*}";;
  *) cd -- "$0";;
esac

또는

cd -- "$(dirname -- "$0"; echo /)"

큰따옴표와 관련하여 잘못된 질문을 하셨습니다. "$0"매개변수의 값입니다 0.$00따옴표 없이는 각 요소의 문자에서 분할된 매개변수 값입니다 IFS. 이는 와일드카드 패턴으로 해석되고 일치하는 파일(있는 경우)로 대체됩니다(후자는 와일드카드가 꺼지지 않은 경우에만 해당).. 매개변수의 값이 0각 요소의 문자에서 분할된 다음 와일드카드 패턴으로 해석되어 일치하는 파일이 있는 경우 대체된다는 의미는 아닙니다 IFS(후자는 와일드카드가 꺼지지 않은 경우에만 해당). 매개변수의 값을 의미합니다 0. 그러니 무슨 뜻인지 적어보세요: "$0".

테스트가 차단되지 않는 유일한 이유는 문제의 이름을 사용하려고 하지 않고 이 특정 시나리오에서 오류를 수정하는 특정 셸을 사용하여 테스트하고 있기 때문입니다. 이와 같은 디렉토리 이름을 사용하면 foo bar명령에 두 개의 인수를 전달하게 되며 foobash의 명령은 이를 "연결, 공백 및 로 얻은 디렉토리로 변경"으로 해석하므로 올바른 이름이 재구성됩니다. 다른 쉘에서는 이를 "가짜 인수에 대한 불만", "디렉토리로 변경" 또는 "현재 작업 디렉터리에서 로 대체하여 얻은 디렉터리로 변경"으로 해석할 수 있습니다. 예를 들어 bash를 사용하면 이름에 두 개의 연속 공백이 포함되어 있으면 스크립트가 실패합니다.barcdcdfoobarfoofoobar

관련 정보