1. 사용 명령어 |
(1) cd
(2) dirname
2. 키워드 & 사용처 |
(1) 키워드
절대 경로, 상대 경로, 전체 경로, cron
(2) 사용처
cron 동에서 스크립트를 전체 경로로 실행할 때 상대 경로로 실행한 것과 같은 동작을 하고 싶을 때 사용합니다.
3. 실행 예제 |
$ cd /home/park
$ /home/park/myapp/dirname.sh
START
END
4. 스크립트 |
#!/bin/sh
cd "$(dirname "$0")" ①
./start.sh
./end.sh
5. 해설 |
이 스크립트는 두 외부 파일 start.sh와 end.sh를 순서대로 실행합니다. 여기서 start.sh와 end.sh 두 파일은 /home/park/myapp 디렉터리에 설치되어 있고 각 파일의 내용은 "START", "END"입니다.
그런데 셸 스크립트 내부에서 다른 셸 스크립트를 실행할 때는 경로에 주의해야 합니다. 그렇지 않으면 아래 예제처럼 만들지도 모릅니다.
#!/bin/sh
./start.sh
./end.sh
스크립트를 작성할 때는 셸 스크립트 파일이 저장된 디렉터리를 현재 디렉터리로 작업하는 일이 많으므로 위의 스크립트는 정상적으로 동작합니다. 하지만 스크립트를 완성해서 cron에 등록해서 정기적으로 실행한다면 이 스크립트는 다음처럼 에러를 발생할지도 모릅니다.
/home/park/myapp/dirname.sh: line 3: ./start.sh: No such file or directory
/home/park/myapp/dirname.sh: line 4: ./end.sh: No such file or directory
이처럼 직접 실행할 땐 정상이었지만 cron에 등록해서 배치 처리할 때 제대로 동작하지 않는 상황은 심심치 않게 벌어집니다. 이것은 cron 실행 시 현재 디렉터리가 cron 실행 사용자의 홈 디렉터리가 되기 때문입니다. 즉, cron에서 dirname.sh가 실행되면 현재 디렉터리는 /home/park가 되어 여기서 ./start.sh를 지정하면 /home/park/start.sh 파일을 찾게 됩니다. 스크립트 내부에서 다른 셸 스크립트를 실행하는 프로그램은 아래처럼 외부 스크립트 파일을 전체 경로로 지정하는 방법도 사용합니다.
#!/bin/sh
/home/park/myapp/start.sh
/home/park/myapp/end.sh
하지만 이때 스크립트가 있는 디렉터리(myapp) 이름이 바뀌면 문제가 생기며 이식성도 낮습니다. 따라서 상대 경로를 사용하고 싶기 마련입니다. 이런 문제를 해결하려면 셸 스크립트가 일단 '자신이 지정된 디렉터리에 cd 명령어로 이동해서 처리를 시작하도록' 만들면 됩니다.
①에서 사용하는 dirname 명령어는 전체 경로가 오면 디렉터리 부분을 추출할 수 있습니다. $0은 실행된 셸의 명령어 자체를 뜻하는 변수로 이 예제에서는 "/home/park/myapp/dirname.sh"가 들어 있습니다.
$ dirname "/home/park/myapp/dirname.sh"
/home/park/myapp
$()은 명령어 치환 표기로 명령어 출력을 그대로 스크립트에서 이용할 수 있습니다. 즉 ①은 'dirname "$0" 출력 결과 디렉터리에 cd 명령어로 이동한다' 라는 의미입니다. 이 예제에서라면 /home/park/myapp 디렉터리에 cd 명령어로 이동합니다.
이렇게 하면 셸 스크립트는 자신이 존재하는 디렉터리로 cd 명령어를 써서 이동할 수있습니다. 따라서 상대 경로이거나 절대 경로이거나 상관없이 외부 셸 스크립트를 상대 결로로 실행할 수 있습니다.
<주의사항>
- 디렉터리명에 스페이스(공백문자)가 포함되더라도 정상적으로 동작하도록①에서 $0 및 명령어 치환 전체를 큰따옴표 기호로 감쌉니다..
- dirname 명령어를 쓰지 않아도 다음처럼 작성할 수 있습니다.
cd "${0%/*}"
이것은 셸 파라미터 확장을 이용한 예입니다. ${parameter%word}라고 하면 변수 parameter 값에서 word에 후방 일치하는 부분을 삭제한 값을 취득할 수 있습니다. 즉 word로 /*가 지정되었으므로 '변수 $0 뒤에서부터 "/임의의 문자열"을 삭제한 값' 즉, 디렉터리 부분만 얻을 수 있습니다. dirname 명령어라는 외부 명령어를 쓰지 않아도 셸 기능만으로 구현 가능하므로 이쪽을 선호하는 사람도 있습니다.
참고서적 : 유닉스 리눅스 셸 스크립트 예제 사전
'IT 이야기 > Linux 셸 스크립트' 카테고리의 다른 글
[Linux 셸 스크립트] 파일처리 - 025 디렉터리 이동한 다음 간단히 원래 장소로 돌아가기 (0) | 2021.03.16 |
---|---|
[Linux 셸 스크립트] 파일처리 - 024 명령어 사용법을 표시할 때 현재 파일명 표시하기 (0) | 2021.03.16 |
[Linux 셸 스크립트] 변환처리 - 022 히어 도큐먼트에서 변수 확장하지 않고 그대로 $str처럼 표시하기 (0) | 2021.03.11 |
[Linux 셸 스크립트] 변환처리 - 021 미정의 변수를 에러로 처리해서 실수 방지하기 (0) | 2021.03.11 |
[Linux 셸 스크립트] 변환처리 - 020 명령어 출력 결과를 파일명에 포함해서 그 파일명을 대상으로 명령어를 실행할 때 보기 쉽게 하기 (0) | 2021.03.05 |
댓글