시나리오는 다음과 같습니다.
foo/
> data/
> stuff/
> scripts/ -> /.../generic/scripts
어떤 위치(다른 폴더 또는 폴더 내)에서 호출될 때 foo/scripts/bar.sh
스크립트를 사용할 수 있기를 원합니다 foo/data
.foo/stuff
그러나 방금 사용하면 foo_dir='dirname $0'/..
심볼릭 링크가 가리키는 디렉토리로 이동합니다! (그리고 generic
대신에 얻으십시오 foo
!)
일부 패턴을 사용하여 끝 부분을 먹으면 $0
디렉터리 내부에서 스크립트를 호출할 수도 있기 때문에 작동하지 않습니다.
그래서 결국 제가 발견한 유일한 것은 다음과 같은 매우 추악한 것이었습니다.
dir=`dirname $0`
cd $dir
dir=`pwd | sed -r 's_/[^/]+$__'`
cd -
...하지만 더 좋은 방법이 있을 거라고 확신해요, 그렇죠?
내가 사용하는 것은:
dir=$( dirname $( cd `dirname $0`; pwd ) )
완벽할지는 모르겠지만 기대한 만큼의 성능을 발휘하는 것 같습니다.
답변1
다음 한 줄을 사용할 수 있습니다.
DIR="$(cd "$( dirname "$0" )" && pwd )"
답변2
처음으로 질문을 더 자세히 읽지 못해 죄송합니다.
바꾸다:
foo_dir = $(dirname $0)/..
어때요?
foo_dir = $(dirname $(dirname $0))
그러나 이는 $0에 디렉터리 구성 요소가 하나 이상 있는 경우에만 작동합니다. 이 보증이 있습니까?
답변3
예, ..
심볼릭 링크의 존재는 실제 문제입니다. 롭 파이크가 썼다.이 주제에 관한 전체 논문.
절대 경로 이름을 ..
사용 하지 않는 것이 좋습니다 .dirname
case $0 in
/*) where="$0" ;;
*) where="$(pwd)/$0" ;;
esac
# postcondition: $where is an absolute pathname for script
# N.B $where = .../foo/scripts/command
base="$(dirname "$(dirname "$where")")"
# postcondition: $base = .../foo
resource="$base/data"
나는 실제로 첫 번째 관용구(가능한 상대 경로명에서 절대 경로명을 복원하는 것)를 사용하고 있으며 ~/bin
특히 이 목적을 위해 내 디렉토리에 스크립트가 있습니다.
절대 경로 이름을 처리하면 dirname
상황이 현명하게 작동합니다.
답변4
귀하의 게시물은 약간 횡설수설하고 일부 진술은 모순되는 것처럼 보이지만 제가 올바르게 이해했다면 귀하는 양식이 있고 $0
해당 부분을 foo/scripts/bar.sh
추출하려고 하는 것입니다 foo
. 또한 경로에 항상 최소한 두 개의 디렉토리가 있도록 보장할 수도 있습니다(만약 그것만 갖고 있다면 bar.sh
문제가 됩니다). 그런 다음 경로의 마지막 두 구성 요소를 제거할 수 있습니다.
DIR=${0%/*/*}
그러나 스크립트를 호출하여 이 작업을 수행할 수 있으며 scripts/bar.sh
, 이 경우 간단한 패턴 교체는 작동하지 않습니다. 통과는 말할 것도 없고 $PATH
조건부로 만들 수도 있습니다.
case $0 in
*/*/*) DIR=${0%/*/*};;
?*/*) DIR=.;;
/*) echo 1>&2 "Storing $0 in the root directory is not supported, aborting."
exit 125;;
*) # The script was called through the `PATH`
IFS=:; set -f; unset DIR
for d in $PATH; do
if [ -x "$d/$0" ]; then
# If you put relative directories in your PATH, you get what you deserve.
DIR=${d%/*};;
fi
done
if [ -z "$DIR" ]; then
echo 1>&2 "$0: Fatal error: I can't find myself."
exit 125
fi
unset IFS; set +f;;
esac