스크립트가 호출되는 디렉토리로 변경하는 안전하거나 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
.$0
0
따옴표 없이는 각 요소의 문자에서 분할된 매개변수 값입니다 IFS
. 이는 와일드카드 패턴으로 해석되고 일치하는 파일(있는 경우)로 대체됩니다(후자는 와일드카드가 꺼지지 않은 경우에만 해당).. 매개변수의 값이 0
각 요소의 문자에서 분할된 다음 와일드카드 패턴으로 해석되어 일치하는 파일이 있는 경우 대체된다는 의미는 아닙니다 IFS
(후자는 와일드카드가 꺼지지 않은 경우에만 해당). 매개변수의 값을 의미합니다 0
. 그러니 무슨 뜻인지 적어보세요: "$0"
.
테스트가 차단되지 않는 유일한 이유는 문제의 이름을 사용하려고 하지 않고 이 특정 시나리오에서 오류를 수정하는 특정 셸을 사용하여 테스트하고 있기 때문입니다. 이와 같은 디렉토리 이름을 사용하면 foo bar
명령에 두 개의 인수를 전달하게 되며 foo
bash의 명령은 이를 "연결, 공백 및 로 얻은 디렉토리로 변경"으로 해석하므로 올바른 이름이 재구성됩니다. 다른 쉘에서는 이를 "가짜 인수에 대한 불만", "디렉토리로 변경" 또는 "현재 작업 디렉터리에서 로 대체하여 얻은 디렉터리로 변경"으로 해석할 수 있습니다. 예를 들어 bash를 사용하면 이름에 두 개의 연속 공백이 포함되어 있으면 스크립트가 실패합니다.bar
cd
cd
foo
bar
foo
foo
bar