linux 환경에서 개발을 진행하다 보면 편의를 위해서든, 프로그램 구동을 위해서든 다양한 이유로 shell을 접하게 됩니다. 아래 예시와 같은 상황에서 어떻게 shell 파일의 path를 알아내고 이를 활용할 수 있는지 찾아보았고, 잘 정리된 내용이 있어 메모 용도로 작성해 둡니다.

상황

예를 드는 것이 가장 빠르고 정확할 것 같아 예를 이용하겠습니다. 아래와 같은 shell 파일이 작성되었다고 가정합니다.

#!/bin/sh
ssh -i ./aaa.pem root@10.10.10.10

서버 접속 명령어를 shell 파일로 작성해 두고, 이 파일을 ssh.sh 라고 저장하였습니다. 그리고 위에 -i 옵션을 준 것 처럼 로그인 key 파일을 지정하게 하였으므로, aaa.pem 파일을 shell 파일과 같은 경로에 둡니다. (./로 시작하기 때문에 같은 경로에 있으면 됩니다.)

이제 해당 shell을 아래와 같이 실행합니다.

$ ./ssh.sh

이렇게 실행하면 아마 정상적으로 잘 동작할 겁니다. 아무런 문제가 없어요.

왜 찾게 되었을까?

잘 사용하고 있었는데, 문제가 발생했습니다. 해당 shell파일의 경로가 아닌, 다른 경로에서 shell을 실행한다면 다음처럼 실행할 겁니다.

$ ./bin/ssh.sh

shell 파일 자체는 잘 실행될 겁니다. 그런데 그 안에서 aaa.pem 파일을 찾을 수 없다면서 에러가 발생합니다.

이는 당연한 결과입니다. shell파일 안에서 pem 파일의 경로를 ./ 로 지정하였지만, 실제 동작에서는 이 ./ 경로가 내가 지금 위치한 경로, 즉 shell파일의 한 단계 상위인 ../ 로 인식하게 됩니다. sh 파일 안에 있는 내용들을 단순히 지금 이 위치에서 주르륵 실행해주는 것이라고 보면 됩니다. 따라서 sh 파일과 동일한 경로에 두었던 pem 파일은 못찾는 것이 당연합니다. 아마 다음과 같이 shell이 변경되면 실행이 될 겁니다.

#!/bin/sh
ssh -i ./bin/aaa.pem root@10.10.10.10

그런데 이렇게 하면 shell파일과 pem 파일을 같은 폴더에 두고 쉽게 실행하려고 했던 생각이 틀어지게 됩니다. 매번 수정을 해줄 바에는 차라리 입력하는게 빠릅니다. 이렇게 실행되는 shell 자체의 경로를 찾아야만 pem 파일을 자연스럽게 찾아가게 될 테니, 그 경로를 알아내려고 했던 것입니다.

경로를 찾아가는 방법

기본지식

shell파일 내에서 인자를 아무것도 주지 않았을 때, 0번째 index 로 넘어오는 것은 그 shell의 실행 명령문입니다. 다음곽 같이 확인할 수 있습니다.

#!/bin/sh
echo 'PARAM:' $0

라는 파일을 bbb.sh 라고 저장하고,

$ ./bin/bbb.sh

로 실행하면,

PARAM: ./bin/bbb.sh

라고 출력됩니다.

dirname 을 이용한 경로 접근

dirname 명령어 뒤에 특정 파일의 어떠한 경로를 넣으면 directory 만을 반환합니다. 위에서 나온 $0 에 대해서는 ./bin/ 을 반환합니다. 이를 이용하면 내가 지금 실행하는 곳에서, shell파일까지의 경로를 알아낼 수 있습니다. 그러면 이 상대경로를 이용해서 cd로 이동하고, 그 안에서 pwd 명령어를 입력하게 되면 해당 shell의 절대 경로를 알아낼 수 있습니다.

처음에 예로 들었던 ssh.sh 파일의 내용을 다음과 같이 변경합니다.

#!/bin/sh
RELATIVE_DIR=`dirname "$0"`

cd $RELATIVE_DIR

PEM_PATH=`pwd -P`

ssh -i $PEM_PATH/aaa.pem root@10.10.10.10

이렇게 변경하고

$ ./bin/ssh.sh

이렇게 실행하게 되면, RELATIVE_DIR에는 ./bin 이 할당되고, cd ./bin으로 이동한 뒤에 pwd -P로 shell파일의 절대 경로를 알아낸 뒤에, 같은 위치에 있는 pem 파일을 찾아 ssh 접속을 하는 개념입니다.

줄여보자

어려운 개념은 아니기 때문에, 다음과 같이 줄여서 쓸 수 있습니다. 조금 더 간단한 shell파일이 완성되었습니다.

#!/bin/sh
PEM_PATH="$( cd "$( dirname "$0" )" && pwd -P )"
ssh -i $PEM_PATH/aaa.pem root@10.10.10.10

출처 및 참고자료


Leave a comment