2015년 9월 10일 목요일

Shell script 안에서 선언한 변수를 스크립트 외부에서도 사용하려면

나의 유닉스/리눅스 지식은 여전히 얕고, 또 특정 분야에만 편중되어 있음을 솔직하게 시인한다!

어제 A5-miseq에 포함된 samtools/bcftools 문제로 사소한 문제를 겪으면서 이와 관련한 해결 방안을 체계적으로 정리해야 되겠다는 생각을 갖게 되었다. A5-miseq 파이프라인을 실행하면 총 다섯 단계를 거쳐 전체 과정이 실행된다. 이때 꽤 많은 프로그램들을 불러야 하므로 패키지의 bin 디렉토리를 전부 PATH 환경변수에 추가하도록 .bash_profile을 설정해 두었었다.


그러면 뭐가 문제인가? /usr/local/bin에는 좀 더 최신 버전의 samtools가 있다는 것이다.

이를 해결하기 위해서 .bash_profile에서는 A5-miseq의 bin 디렉토리를 PATH에 추가하지 않기로 하였다. 그러면 A5-miseq을 실행하려면 어떻게 하면 되는가? 가장 간단하게는 shell에서 다음과 같이 한 다음에 a5_pipeline.pl을 실행하면 된다.

export PATH=$PATH:/usr/local/apps/a5_miseq_linux_20141120/bin/

혹은 스크립트를 다음과 같이 만들어서 PATH 선언과 동시에 실행을 해도 된다. 여기에서는 export 명령을 쓸 이유가 없다. 내가 늘 교과서처럼 여기는 Mark G. Sobell의 3판(1995년, 좀 오래되었다) 293쪽을 보면 "The export command (below) makes the new value of PATH accessible to subshells and other shells you may invoke during the login session"이라고 적혀 있다.

#!/bin/env bash
PATH=$PATH:/usr/local/apps/a5_miseq_linux_20141120/bin/
a5_pipeline.pl BL21-20x_1.fastq BL21-20x_2.fastq testAssembly

이 스크립트의 실행이 종료되고 난 뒤 PATH 변수에는 A5-miseq의 bin이 더 이상 남아있지 않다. 스크립트 내에서 export를 사용하는 여부에 관계 없이 스크립트 종료와 함께 '펑' 사라지는 것이다. 그러면 스크립트 내에서 선언한 변수가 그 스크립트의 종료 이후에도 계속 유지되게 하려면 어떻게 하면 되는가? 바로 source 혹은 '.' 명령으로 그 스크립트를 실행하면 된다.

마지막 질문은 source로 실행하는 스크립트 내부에서 export를 쓸 필요가 있느냐이다. 테스트를 해 보면 필요하지는 않아 보인다.

이 문서를 작성하기 위해 다음의 글을 참고하였다. 물론 아직까지는 여기에서 설명하는 모는 것을 전부 이해하고 있지는 못한 상태이다.

http://stackoverflow.com/questions/16618071/export-a-variable-to-the-environment-from-a-bash-script-without-sourcing-it

댓글 없음: