`#! / usr / bin / env 명령 –argument`가있는 Shebang 줄이 Linux에서 실패합니다 리눅스 상자에서 오류가 발생합니다. linux%

간단한 스크립트가 있습니다.

#!/usr/bin/env ruby --verbose
# script.rb
puts "hi"

내 OSX 상자에서 정상적으로 실행됩니다.

osx% ./script.rb
hi

그러나 내 리눅스 상자에서 오류가 발생합니다.

linux% ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

shebang 라인을 수동으로 실행하면 정상적으로 작동합니다.

linux% /usr/bin/env ruby --verbose ./script.rb
hi

그러나 ruby --verbose단일 인수로 묶으면 오류를 복제 할 수 있습니다.env

linux% /usr/bin/env "ruby --verbose" ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

그래서 이것이 envShebang 라인의 재설정을 해석하는 방법에 관한 문제라고 생각합니다 . GNU coreutils 8.4를 사용하고 있습니다 env:

linux% /usr/bin/env --version
env (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Richard Mlynarik and David MacKenzie.

정말 이상해 보인다. 이 버전의 일반적인 문제입니까 env, 아니면 내가 모르는 다른 문제가 있습니까?



답변

BSD와 달리 Linux는 shebang 명령 (이 경우 env)에 단일 인수 만 전달하기 때문입니다.

이것에 대해서는 StackOverflow에서 광범위하게 논의되었습니다 .


답변

@rampion 주석을 통해 이것을 찾았습니다.

커널이 파일의 처음 두 문자를 처리하여 #!을 찾습니다. 그것들이 발견되면 공백이 아닌 문자를 찾는 모든 공백 문자를 건너 뛰고 다른 스크립트가 아닌 실제 실행 파일이어야하는 인터프리터 경로를 추출하지만 Linux는 재귀 스크립트 처리를 허용하도록 확장합니다. 그런 다음 공백이 아닌 첫 번째 문자로 건너 뛰고 다음 줄 바꿈 문자로 가져 가서 명령에 단일 인수로 전달합니다. 따옴표 나 다른 메타 문자에 대한 ‘쉘’처리는 없습니다. 그것은 모두 매우 간단하고 무차별적인 힘입니다. 따라서 당신은 거기에 옵션으로 공상을 얻을 수 없습니다. 정확히 하나의 인수 공백이 포함되어 있으며 ‘perl -w’는 커널이 여기에서보고 전달하는 것입니다.

출처 : http://lists.gnu.org/archive/html/bug-sh-utils/2002-04/msg00020.html