- 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어
명령어: .(닷 명령어)
키워드: 외부 파일, 읽기, 정의 파일
사용처: 여러 셸 스크립트에서 공통된 설정값이나 함수를 사용하는데 그런 값과 함수를 외부 파일로 정의하고 싶을 때
실행예제
$ ./source.sh
21:24:49
large-file.tar.gz -> /var/tmp/myapp/large-file.tar.gz
21:24:57
스크립트
#!/bin/sh
. ./env.sh #------------- 1
nowtime
cp -i -v large-file.tar.gz "$WORK_DIR"
nowtime
해설
이 스크립트는 지정한 작업 디렉터리에 큰 파일을 복사해서 그 처리 시간을 측정하는 간단한 예제입니다. large-file.tar.gz는 파일 크기가 크다고 가정합니다.
1
에서 env.sh 라는 정의 파일을 .(닷 명령어)으로 읽어들입니다. env.sh 내용은 [파일1]과 같은데 임시 디렉터리를 지정하는 변수($WORK_DIR)와 현재 시간을 date 명령어로 표시하는 함수가 정의되어 있습니다.
-
파일1
env.sh 파일 내용WORK_DIR=/var/tmp/myapp nowtime() { date +%X }
이렇듯 변수나 함수를 정의하는데 같은 정의를 다른 스크립트에서도 공통으로 쓰고 싶을 때가 있습니다. 일일이 스크립트마다 정의를 작성하는 것은 귀찮기도 하고 나중에 값이 바뀌면 전부 수정해야 하는 문제가 있습니다. 수정을 빠트리는 실수가 있으면 문제가 생기기도 합니다.
이런 일을 방지하기 위해 변수나 함수 정의를 공통 외부 파일에 설정하고 스크립트에서 공통 파일을 읽어옵니다. 그럴 때 쓰는 것이 .(닷 명령어) 입니다.
.(닷 명령어)으로 외부 파일을 읽어들일 때 마치 소스 파일이 그대로 삽입된 것처럼 파일 내부 명령어가 실행됩니다. 즉, 1
은 [파일1] 내용을 그대로 해당 장소에 에디터로 복사해 붙인것 처럼 동작합니다. 따라서 외부 파일에서 정의한 변수와 함수를 다룰 수 있습니다.
한편, 1
에서 “sh env.sh”로 셸 스크립트를 실행할 때는 현재 셸과는 다른 프로세스로 동작하므로 변수는 이어받지 않습니다. 다음 실행 예처럼 이 스크립트를 실행해도 1
은 다른 프로세스로 실행되므로 변수와 함수 정의가 원래 스크립트에 반영되지 않습니다. 결과로 다음처럼 에러가 발생합니다.
-
변수와 함수 정의가 이어지지 않으므로 에러 발생
$ ./source.sh ./source.sh: line 5: nowtime: command not found cp: ./large-file.tar.gz and large-file.tar.gz are identical (not copied). ./source.sh: line 7: nowtime: command not found
.(닷 명령어)으로 읽어들이는 것과 다른 프로세스로 기동하는 것은 서로 다르다는 것을 이해하기 바랍니다. env.sh 파일에는 첫 줄에 #!/bin/sh(셔뱅*/shebang)이 없는데 단독으로 실행되지 않고 다른 셸 스크립트에서 읽어서 실행할 것을 전제로 만들었기 때문입니다.
한편, bash라면 .과 같은 동작을 하는 source 명령어도 씁니다. 닷 하나는 잘 안보이므로 bash 환경에서만 쓴다면 source 명령어로 더 보기 쉽게 작성할 수 있습니다.
source env.sh
.(닷 명령어)좋은점, 나쁜점
외부 파일을 쓰면 의존 관계가 생깁니다. 즉, 어떤 셸 스크립트를 다른 환경에 이식할 때 읽어들이는 외부 파일도 함께 이동해야만 합니다.
한편, 셸 스크립트의 좋은 점으로 스크립트 파일 하나를 복사하면 이동이 끝난다는 간편함이 있습니다. 닷 명령어를 써서 발생하는 의존 관계는 이런 간편함을 저해시킵니다.
따라서 의존 관계가 싫어서 닷 명령어를 쓰지 않는 사람도 있습니다. 특히 팀으로 작업할 때 또는 장기적으로 오래 사용할 스크립트에 대한 방침을 미리 정해둬야합니다.
주의사항
-
닷 명령어는 대상 파일이 존재하지 않으면 에러가 발생합니다. 따라서 읽어들일 설정 파일은 test 명령어 -f 연산자로 파일 존재 여부를 미리 확인해둬야 합니다. 다음 예는 리눅스(CentOS)와 sshd 기동 스크립트 일부입니다. /etc/sysconfig/sshd 라는 설정 파일이 존재하는지 확인한 다음 &&(AND 연산자)와 닷 명령어로 설정 파일을 읽어들입니다.
[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd
닷 명령어를 쓸 때는 주로 이렇게 작성하므로 잘 기억해두기 바랍니다.
셔뱅 : 유닉스 스크립트에서 #1으로 시작하는 첫 줄을 가리키며 스크립트를 읽어들일 인터프린터를 지정합니다. shabang/sha-bang, hashbang/hash-bang, hash-pling, pound-bang, hash-exclam 등 다양한 이름이 있지만 일반적으로 shebang을 사용합니다.