Shebang Line을 바로쓰자

보통 UNIX Shell Script를 만들 때 파일의 첫 줄에

#!/bin/sh

처럼 넣는 것을 shebang line이라고 한다.

이것은 어떤 스크립트파일이 실행될 수 있도록 권한을 주고 해당 스크립트를 실행시켰을 때 shebang line 이후의 줄들을 어떤 명령이 해석할 것인가를 지정해주는 것으로 Perl같은 동적 스크립트언어( Python,Ruby도 마찬가지)에도 마찬가지로 다음과 같이 적용된다.

<test.pl>
#!/usr/bin/perl
print "Hello World\n";

<실행>
chmod a+x test.pl
./test.pl

만약에 shebang line이 없는 상태에서 적절한 해석기를 통해 실행시키려면

perl test.pl

처럼 [스크립트해석기] [스크립트] 형식으로 명령을 실행시켜야 할 것이다. 이 경우에는 해석기를 지정하여 스크립트를 실행시키므로 스크립트 파일에 굳이 shebang line을 쓸 필요가 없다.

그런데 가끔 보면 Windows용 Perl ( Activestate Perl 또는 Strawberry Perl )을 사용해서 Perl 프로그래밍 하는 사람들이

#!C:/Perl/bin/perl.exe

print "Hello World\n";

이런식으로 UNIX에서 했던 것과 같이 perl실행파일이 있는 Windows 드라이브 상의 path를 그대로 요상한 모양으로 적어주는 경우를 종종 보는데, 간단히 결론만 말하자면 Windows에서는 shebang line은 아무런 의미가 없다.

스크립트를 Perl을 통해 실행시키고자 하면 unix에서와 마찬가지로 perl 바이너리가 path에 잡혀 있다면

perl test.pl

하면 실행된다. 그럼 unix에서 스크립트 파일을 실행가능하도록 해서 스크립트 파일이름만으로 실행되게 하려면 어떻게 해야할까?

방법은 단지 Windows가 특정확장자의 파일을 어떤 실행파일을 통해서 열 것인가를 지정하는 기능을 사용하는 것이다.( txt파일을 더블클릭하면 notepad가 실행되며 파일이 열리는 것을 떠올리면 됨 ) 이것은 파일탐색기 메뉴를 통해서 설정할 수도 있고 다음과 같은 dos명령을 통해서도 설정할 수 있다.

ASSOC .pl=PerlScript
FTYPE PerlScript=C:\strawberry\perl\bin\perl.exe %1 %*

하지만 개인적으로 Windows에서 이런 식으로 사용하는 건 별로 좋아하지 않는다.

다시 말하면 Windows에서 shebang line은 단지 장식용(?)일 뿐이다. 따라서 응용력을 과도하게 발휘해서 이상한 모양의 shebang line을 쓰지말고 나중에 UNIX에 가져가서라도 그냥 쓸 수 있게 보통 UNIX에서 하던 것처럼 그냥  #!/usr/bin/perl 이라고 해주자.

그런데 UNIX에서도 shebang line이 꼭 #!/usr/bin/perl 일 필요는 없다. 대게는 UNIX에서 기본으로 perl 바이너리가 /usr/bin에 있기 때문에 저렇게 쓰는 것이지 만약에 자신만의 Perl을 소스를 받아서 따로 컴파일해서 /usr/local/bin/perl 에 깔았고 그 Perl을 이용하고 싶으면  shebang line을  #!/usr/local/bin/perl 이라고 지정하면 된다.

그런데 시스템에 여러 종류의 Perl이 존재할 경우 필요할 때마다 shebang line을 변경하는 것은 매우 귀찮은 일일 것이다. 이런 경우에는 스크립트 소스는 건드리지 않고 PATH 환경변수만 적절하게 바꿔서 유연하게 사용할 수 있는 방법이 있다.

사용하고 싶은 Perl 바이너리가 있는 경로를 PATH환경변수에 세팅하고 ( 만약 perl 바이너리가 PATH환경변수의 여러 곳에 있다면 예- /usr/local/bin, /usr/bin PATH환경변수에 먼저 나오는 것이 우선된다. )

#!/usr/bin/env perl

이라고 shebang line을 적어주면 PATH환경변수에서 가장 우선되는 perl 바이너리를 찾아 스크립트를 실행한다.

여기서 env는 뒤따르는 명령의 수정된 환경변수를 스크립트 해석시 적용하는 명령이다. perl은 컴파일되서 설치될 때 자신만의 고유의 라이브러리 경로등의 정보를 가지는데, 따라서 어떤 perl 바이너리가 실행되느냐에 따라 그러한 정보들이 다르게 적용되므로 env를 통해서 실제 실행되는 바이너리의 환경을 자동으로 적용될 수 있게 해주는 것이다.

0 TrackBacks

Listed below are links to blogs that reference this entry: Shebang Line을 바로쓰자.

TrackBack URL for this entry: http://aero.sarang.net/cgi-bin/mt/mt-tb.cgi/139

6 Comments

Aero님의 글 언제나 바이블처럼 새겨서 보고 있습니다.
perl의 재미를 붙여나가고 있는 중이어서 Aero님의 글은 한참 앞서간 선배님의 글같습니다.

shebang입니다만, shebang이 윈도우에서 의미가 있는 경우가 딱 한가지 있다고 생각하는데요,
아파치 httpd.conf에서
AddHandler cgi-script .cgi 로 되어 있는 경우 이 확장명은 무조건 해석기를 shebang에서 찾으려고 하는 것 같습니다.
.groovy에서도 shebang이 지원되어서 .groovy로 cgi를 해보려다 어찌어찌 해서 알게되었습니다. (결국은 .groovy를 AddHandler로 실행시키는 것은 포기하고, groovy native launcher와 httpd.conf의 'ScriptInterpreterSource registry'로 성공했습니다만...)

아무쪼록 잘 부탁드립니다.

잠깐 스쳐가는 생각에 다시 적게 되었습니다.
억지스러운 환경입니다만, 혹시 windows에서 cygwin설치하였을 경우, bash등의 shell을 사용하고 있을 경우에 shebang을 볼까?? 하는 생각이 들었습니다.
cygwin은 설치하고 있지 않아 확인은 하지 못하고, ...일까? 하는 생각만 적습니다. 매우 실례했습니다.

aero Author Profile Page said:

@crowdy.myid.net unix의 경우 shebang line을 인식하고 해석하는 건 shell입니다. Windows cmd는 이런 기능이 없으니깐 당연히 의미가 없는 것이구요 apache는 unix의 shell처럼 shebang line을 인식한다는 군요 그래서 windows상의 cgi에서도 적용이 되는 것이고 그런데 http://codingforums.com/showthread.php?t=159726http://vijayk.blogspot.com/2007/10/apache-cgi-scripts-on-windows.html 을 보면 win32 apache에서도 shebang line을 요상하게 바꾸지 않고 하는 방법이 있는것 같습니다.

그리고 cygwin의 경우 당연히 (?) cygwin상의 shell이 shebang라인을 인식할 것 같습니다. :)

cw said:

제 블로그에 들러주셔서 고맙습니다.
그렇군요.
윈도우에서 그 라인을 지워도 걍 실행이 되네요.
오늘 좋은 내용을 알았습니다.
앞으로 perl공부하면서 종종 들를께요.

재미있는 것을 발견했습니다.
윈도우즈용 cgi때문에 아직 shebang을 사용하고 있습니다.

그런데 이렇게 적어두었을 때
#!c:\usr\local\perl.exe -cw

다음과 같이 동작하는 것을 발견했습니다.

C:\>gmailchecker.pl
C:\gmailchecker.pl syntax OK

C:\>

어쩌면 cmd.exe는 shebang을 보지 않더라도 제가 사용한 perl은 activeperl인데, activeperl은 살짝 보는 것 같기도 합니다. (strawberry는 어떤지 잘 모르겠습니다.)

이상 정보공유였습니다.
잘 부탁드리겠습니다.

aero Author Profile Page said:

@crowdy 제 기억으로는 ActiveState Perl을 깔면 .pl 확장자등을 자동으로 Perl 바이너리가 읽어 해석하도록 되는게 기본일겁니다.
그래서 cmd상에서 pl확장자 파일을 그냥 치면 Perl이 그 파일을 읽어서 실행하죠( txt확장자 파일 이름만 치고 엔터치면 notepad가 열리면서 파일내용을 보여주는 식 )

ASSOC .pl=PerlScript
FTYPE PerlScript=C:\strawberry\perl\bin\perl.exe %1 %*

같은 것이 설치과정중에 자동으로 세팅되는 것이라고나 할까요.

따라서 shebang line이 어떤 것이든 상관이 없을겁니다.(말씀드렸던대로 장식품)

Leave a comment

About this Entry

This page contains a single entry by aero published on July 27, 2009 3:26 PM.

Catalyst vs Ruby on Rails was the previous entry in this blog.

ssh를 socks proxy를 통해서 접속하기 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by Movable Type 4.21-en