[완료]스트립트를 절대경로로 실행할 때 스크립트의 절대경로를 구하는 다른 방법?

dcmru의 이미지
1800
points
2
points

스크립트를 현재 디렉토리에서 실행하거나 다른 디렉토리에서 실행할 때

스크립트의 절대경로를 구하고자 합니다.

아래와 같이 짜봤는데요, 쉽게 구할 수 있을 다른 방법이 있을까요?

#!/bin/sh
# file name : test

EXEC_FILE=$0
echo $EXEC_FILE

if [ "$EXEC_FILE" = "./test" ] || [ "$EXEC_FILE" = "test" ]; then
        FULL_PATH=`pwd`
        echo "$FULL_PATH"
else
        FULL_PATH=`echo $EXEC_FILE | sed 's/test//'`
        echo "$FULL_PATH"
fi

exit 0

feanor의 이미지
10709
points

dirname & realpath

2
points

BASE=$(dirname $(realpath $0))

하시면 됩니다.

chronon의 이미지
1730
points

realpath

0
points

readlink -f $0

을 하면 reallink 명령어가 realpath() 함수를 이용해 절대 경로를 출력해 줍니다.
구글링 하다 찾아 나름대로 어렵게 찾아서 여기에 답글을 달아 둡니다.

jg의 이미지
3125
points

순수 bash/sh 만을 이용한 방법은

2
points

FULL_PATH=$(cd "${EXEC_FILE%${EXEC_FILE##*/}}"; echo "$PWD")

feanor*님이 보여주신 것과 거의 비슷하지만
현재 디렉토리도 절대 경로로 보여줍니다.

jg의 이미지
3125
points

버그 수정..

2
points

FULL_PATH=$(tmp="${EXEC_FILE%${EXEC_FILE##*/}}"; cd "${tmp:-$PWD}"; echo "$PWD")

# 절대경로 (최상위)
EXEC_FILE=/test
FULL_PATH=$(tmp="${EXEC_FILE%${EXEC_FILE##*/}}"; cd "${tmp:-$PWD}"; echo "$PWD")
echo "$FULL_PATH"
# 절대경로
EXEC_FILE=/usr/bin/test
FULL_PATH=$(tmp="${EXEC_FILE%${EXEC_FILE##*/}}"; cd "${tmp:-$PWD}"; echo "$PWD")
echo "$FULL_PATH"
# 현재경로 (./)
EXEC_FILE=./test
FULL_PATH=$(tmp="${EXEC_FILE%${EXEC_FILE##*/}}"; cd "${tmp:-$PWD}"; echo "$PWD")
echo "$FULL_PATH"
# 현재경로 ()
EXEC_FILE=test
FULL_PATH=$(tmp="${EXEC_FILE%${EXEC_FILE##*/}}"; cd "${tmp:-$PWD}"; echo "$PWD")
echo "$FULL_PATH"

dcmru의 이미지
1800
points

답변 감사드립니다.

0
points

답변 감사드립니다.

ps. feanor 님 realpath 라는 명령어가 현재 테스트 환경에서는 안보입니다.

jg 님 FULL_PATH=$(tmp="${EXEC_FILE%${EXEC_FILE##*/}}"; cd "${tmp:-$PWD}"; echo "$PWD") 에서

${EXEC_FILE%${EXEC_FILE##*/}} 과 "${tmp:-$PWD}"; 의 설명을 부탁드려도 될까요?

${EXEC_FILE##*/} 는 실행파일의 이름을 ${EXEC_FILE%${EXEC_FILE##*/}} 는 패스를 출력하네요.

어떻게 그렇게 되는지 설명을 부탁드립니다.

----------------
노력만이 살길이다.

jg의 이미지
3125
points

bash man 페이지에 나와있습니다.

0
points

${EXEC_PATH##*/}
${변수##패턴}

에서 ${변수##패턴} 의 형태로 쓰게 되면
변수로부터 값을 읽어와서 왼쪽에서부터 패턴과 일치하는 최대 부분을
삭제합니다. 따라서 ${EXEC_FILE##*/} 은 왼쪽에서부터 */ 과 최대한 일치하는 부분을 삭제하여
실행파일 이름을 나타내게 됩니다. 일치하지 않는 경우는 그냥 변수 내용그대로를 나타냅니다.
참고로 #를 한 번만 사용한 꼴인 ${변수#패턴} 은 최소한 일치하는 부분을 삭제합니다.

EXEC_FILE=${EXEC_PATH##*/}

${EXEC_PATH%$EXEC_FILE}
${변수%패턴}

# 과는 반대로 % 를 사용하게 되면 오른쪽에서부터 패턴을 없앱니다.
%% 를 사용하면 최대한의 패턴을 삭제합니다.
(키보드 위치상 # 이 % 보다 상대적으로 왼쪽에 위치하기 때문에 그것으로 기억하시면 쉬울겁니다.)

따라서 EXEC_FILE 변수에서 읽어와 EXEC_PATH로 부터 없앤 문자열을 나타내게 됩니다.
${EXEC_FILE%${EXEC_FILE##*/}} 는 위의 두 표현은 한데 묶어서 표현한 것입니다.

굳이 이렇게 하는 이유는

${EXEC_PATH%/*} 의 경우 /exec 나, exec 와 같은 형태는 제대로된 디렉토리를 가져올 수 없고
각 케이스별로 나누어 다시 처리해주어야 하기 때문에 복잡해지기 때문입니다.

cd 를 사용한 이유는 복잡하게 얽혀있는 디렉토리 예를 들어
/usr/../bin/./ 와 같은 형태를 /bin 과 같은 형태로 만들기 위해
bash에서 가장 효율적인 방법이 그곳으로 직접이동하여 pwd를 출력하는 방법이기 때문입니다.
이것이 바로 realpath 의 역할이기도 합니다.

제가 급하게 수정하느라 미처 생각지 못했는데 아래와 같이 하셔도 되겠습니다.

FULL_PATH=$(cd "${EXEC_FILE%${EXEC_FILE##*/}}./"; echo "$PWD")

외부 툴을 이용하는 것도 좋지만 이 정도면 충분히 효율적이라 생각합니다.

영어로 되긴 했지만 전체 메뉴얼은
man bash 하시길 바랍니다. :)

dcmru의 이미지
1800
points

답변 감사드립니다. ^^

0
points

이해가 되었습니다. 자세한 설명 감사드립니다.
----------------
노력만이 살길이다.

댓글 보기 옵션

원하시는 댓글 전시 방법을 선택한 다음 "설정 저장"을 누르셔서 적용하십시오.