[쉘스크립팅] #! (shebang) 에 따라 인터프리터 실행하기

[code:3oysq0ix]
#!/bin/bash
for ((i=0;i<3;i++)); do
echo $i
done
[/code:3oysq0ix]

이 파일에 실행속성이 없어서 sh script.sh 으로 실행하게 되면…
script.sh: 2: script.sh: Syntax error: Bad for loop variable 이런 오류가 발생합니다.

shebang은 프로그램로더에서 파싱해서 실행시켜주는 것이고,
실제 쉘에서는 #으로 시작하니 주석이 되어 처리되지 않습니다.
즉, 프로그램로더에서 shebang줄을 해석해서 프로그램을 실행하면서, 해당파일을 인터프리팅하게
만들어 줍니다.

물론 실행속성이 있다면, 프로그램로더에 의해 알아서 shebang에 명시된 프로그램을 호출합니다만…
그렇게 하지 않고, 실행속성없이 shebang을 파싱해서 실행해주는 스크립트를 작성해 보았고,
간단한 스크립트이나 꽤나 편리하더군요.

[code:3oysq0ix]
#!/bin/sh
SHEBANG=$(sed -nr ‘1s/^#!\s*//gp’ "$1" 2>/dev/null)
[ -n "$SHEBANG" ] && exec $SHEBANG "$@" && true || "$@"
[/code:3oysq0ix]

실행시 shebang a.pl 이런식으로 사용하면 알아서 shebang에 적힌대로 perl이 실행됩니다.
shebang이 없으면, 그냥 명령을 실행하구요.

참고로 shebang을 사용할때는 절대경로를 사용해야 하기 때문에…
PATH에 있는 프로그램을 사용할때에는
#!/usr/bin/env perl 이런 식으로 사용하는 것이 좋습니다.
이러면 절대 경로를 적지 않아도 되지요.

[code:3oysq0ix]
"~/.vimrc
fun! s:DetectNode()
if getline(1) == ‘#!/usr/bin/env node’
set ft=node
endif
endfun

autocmd BufNewFile,BufRead * call s:DetectNode()
[/code:3oysq0ix]
이것은 shebang줄에 #!/usr/bin/env가 있을경우 파싱해서, 문법강조를 그에 따라 맞춰주는
vim 코드입니다.

새로운 정보 감사드립니다.

전 그동안 $ bash script.sh 같은 식으로 사용해 왔거든요…

[quote="blhole":2b1n7p1a]새로운 정보 감사드립니다.

전 그동안 $ bash script.sh 같은 식으로 사용해 왔거든요…[/quote:2b1n7p1a]

쉘스크립트를 작성할 때 항상 bash를 사용할 수 있는 것은 아닙니다.

예를들어, bash를 로드할 수 없는 환경인 initramfs(리눅스 본부팅 이전의 램디스크 부팅과정)에서
사용할 쉘스크립트를 작성한다면, busybox의 쉘 스크립트를 사용해야 하는데,
bash처럼 덩치가 큰 쉘이 아니라, ash라는 본쉘유형의 쉘이 내장되어 있습니다.
busybox라고 명령하면 사용가능한 명령어가 나오며
busybox sh --help 이런식으로 도움말도 볼 수 있습니다.
vi도 vim과 같이 덩치큰 것이 아니라, 기본적인 vi기능이 들어 있습니다만,
왠만한 필수적인 명령은 다 들어 있죠.

그렇기 때문에… 이러한 환경에서 동작하려면 본쉘스크립팅을 익힐 필요가 있습니다.
무작정 bash문법으로 작성하면 동작을 안하니까요.