shebang 라인에 따라 스크립트를 실행하는 명령이 있습니까?


46

실행 권한이 설정되지 않은 bash 스크립트를 실행하려면 다음을 수행하십시오.

bash script.sh

bash스크립트가 실행 가능하지 않고 올바른 인터프리터를 모른다면 대신 무엇을 사용해야 합니까? shebang 줄에서 인터프리터를 찾아서 스크립트를 실행하는 명령이 있습니까?


재치 bash는 무엇이 잘못 되었나요?
steffen

@ steffen 문제의 파일이 bash 스크립트인지 어떻게 알 수 있습니까?
muru

질문에서 @muru 인용 : "bash 스크립트를 실행하려면 ..."또한 (bash 스크립트가 아니더라도) bash whatever작동 한다면 왜 다른 것을 사용합니까? bash는 거의 모든 * ix 시스템에서 사용 가능하므로 왜 귀찮게
합니까

1
@ steffen 나머지 질문을 읽었습니까? 그들은 말한다면 : "만약 그렇다면 다음을 할 수있다 : ..."와 "만약 내가 올바른 통역사를 모른다 면 배쉬 대신 무엇을 사용해야 합니까?"
muru

@muru : 어쩌면 나는 분명하지 않습니다. 그러나 질문에 명시된 것처럼 / bang 파일에 shebang 행이 있으면 bash는 요청 된 내용을 정확하게 수행합니다. 아래 답변에 따라 펄처럼. bash를 사용하지 않는 장점은 무엇입니까?
steffen

답변:


67

네. 이라고합니다 perl:

perl foo.bash    # works
perl foo.lua     # works
perl foo.clisp   # works
perl foo.csh     # works
perl foo.php     # works
perl foo.gnuplot # works (no arguments)
perl foo.pl      # works (obviously)
perl foo.py      # works
perl foo.sh      # works
perl foo.tcl     # works
perl foo.rb      # works
perl foo.nodejs  # works
perl foo.r       # works
perl foo.oct     # works
perl foo.csharp  # works (no arguments)

이것은 Perl의 문서에 언급되어 있습니다 :

는 IF #!라인은 단어 "펄"나 단어 "든지 indir"는이 이름을 딴 프로그램을 포함하지 않는 #!대신에 펄 인터프리터의 실행을. 이것은 약간 기괴하지만 #!, 프로그램이 SHELL이 / usr / bin / perl임을 알릴 수 있기 때문에 펄 이 아닌 기계를 사용하는 사람들에게 도움이되고 , Perl은 프로그램을 올바른 해석기에 전달합니다.


40
글쎄, 그건 더럽다.
날씬한

1
파일 확장자 .js도 작동합니까?
Pysis

1
또한 기계가하지 않는 것 #!. 나는 지금까지 몇 가지 더 보였고이 문제가 발생하지 않았습니다.
Pysis

1
좋아, 그것은 당신의 예가 파일 에서 여러 shebang 행 보여주기보다는 많은 파일 확장자를 강조하는 것처럼 보였으며, 그 예측이 작동하는 것으로 가정합니다.
Pysis

2
나는 man perlrun그것이 "약간 기괴하다"라는 것을 양적으로 인정하는 것을 좋아 한다 :). 나는 이것이 유닉스가 아닌 환경과 매우 오래된 버전의 유닉스를 목표로 한 호기심으로 취급되어야한다고 생각합니다 .
슬림

25

스크립트가 반드시 shebang을 가질 필요는 없습니다

스크립트가 인터프리터에서 실행 된 경우 shebang 이 전혀 있는지 확신 할 수 없습니다 . 인터프리터에서 실행되는 스크립트는 오두막이 필요하지 않습니다 , 경우 코드를 실행하는 인터프리터를 호출합니다.

따라서 대답은 '아니오'입니다. 스크립트를 실행할 언어 (통역사)가 무엇인지 확실히 알 수있는 명령이 없습니다. 그러나 항상 스크립트 내부를 살펴보고 찾을 수있는 shebang이 있는지 확인할 수 있습니다.

한마디로 규칙 :

  1. 스크립트를 실행할 때 인터프리터를 호출하면 항상 가능한 shebang, 실행 가능 또는 shebang보다 우선합니다.
  2. 실행 가능하지 않고 인터프리터 에서 실행 되는 경우 스크립트는 shebang이 필요하지 않습니다.
  3. 스크립트가 먼저 인터프리터를 호출하지 않고 실행하면, 그것은 필요 (및 사용)이 오두막은 무엇 호출에 통역 찾아, 그리고 그것의 오두막에서 인터프리터를 호출 할 수있는 "권한"을 가지고 실행해야합니다.

그러나 스크립트에 shebang이 없으면 스크립트 내부에 어떤 인터프리터를 사용할지 알려주는 (직접 *) 정보가 없습니다.

라고 한

당신은 물론 항상하는 래퍼 스크립트를 작성할 수 시도 스크립트가 오두막을 가지고 있는지 확인하고 그에서 통역을 읽고, 그 후 발견 인터프리터에서 실행합니다.

#!/usr/bin/env python3
import subprocess
import sys

args = sys.argv[1:]; script = args[0]

try:
    lang = open(script).readlines()[0].replace("#!", "").strip().split()[-1]
    cmd = [lang, script]+args[1:]
    subprocess.call(cmd)
except (PermissionError, FileNotFoundError, IndexError):
    print("No valid shebang found")
  • 그것은 다른 이름으로 저장 tryrun에서 $PATH(예를 들어 ~/bin그것을 확인 존재, 로그 아웃 한 후 다시하지 않는 경우, 디렉토리를 만들) 실행 . 그런 다음 실행하십시오.

    tryrun /path/to/nonexecutablescript

    실행 불가능한 스크립트 pythonbash스크립트 에서 올바른 인터프리터를 호출 (테스트)했습니다 .

설명

  • 스크립트는 단순히 스크립트의 첫 번째 행을 읽고를 제거 #!하고 나머지를 사용하여 인터프리터를 호출합니다.
  • 유효한 인터프리터를 호출하지 못하면 a PermissionError또는 a가 발생 FileNotFoundError합니다.

노트

확장 ( .sh, .py등) 리눅스에서 적절한 통역을 결정하는데 어떤 역할 무엇이든지를 연주되지 않습니다.


(* 물론 코드에서 구문을 결정하기 위해 "스마트"추측 알고리즘을 개발할 수 있습니다.)


좋아, 그것은 리눅스가 어딘가에 구현 된 shebang 추출을 가지고 있지만 (실행 파일에 대한 올바른 해석기를 선택할 수 있음) 독립형 표준 명령으로 제공되지 않는다는 것을 의미합니다.
Aivar

@Aivar가 shebang을 추출하는 것은 문제가 아니지만 코드없이 코드를 실행하는 것은 완벽하게 가능합니다.
Jacob Vlijm

@ Aivar 아, 무슨 말인지 알 겠어. 스크립트가 명령에 언어없이 실행하고 실행하는 경우, 스크립트 인터프리터 다른 방법은 주위를 호출합니다.
Jacob Vlijm

1
@JacobVlijm "리눅스 커널이 스크립트를 실행할 때 어떤 인터프리터를 호출할지 알아 내기 위해 shebang 라인을 사용합니다"와 같이 "스크립트가 인터프리터를 호출합니다"라고 말하지 않을 것입니다.
Paŭlo Ebermann

@ PaŭloEbermann 감사합니다! 물론입니다. 커널은 전체 절차를 어느 쪽이든 처리하지만, 비 유적으로 이해하기에 더 좋을 것이라고 생각하면, 통역사가 무엇을 호출해야하는지 (그리고 실제로는) 처리하도록 "스크립트가 허용"되었다고 말하는 것입니다. 문구에 대해서는 잘 모르지만, 이니셔티브가 스크립트에있는 것처럼 커널이 실제로 작업하는 것처럼 설명하고 싶습니다.
Jacob Vlijm

6

다음과 같은 스크립트로이를 달성 할 수 있습니다.

#!/bin/bash

copy=/tmp/runner.$$
cp $1 ${copy}
chmod u+x ${copy}
${copy}
rm ${copy}

그러므로:

$ echo "echo hello" > myscript
$ ./myscript
bash: ./myscript: Permission denied
$ ./runscript myscript 
hello

나는 이것을하지 않는 것이 좋습니다. 권한이 이유가 있습니다. 권한을 전복하는 프로그램입니다.

shebang 처리는 커널 함수 (Linux 소스 코드- fs/binfmt_script.c)입니다. 기본적으로 스크립트를 직접 호출하는 프로세스는 다음에 대해 알지 못합니다 #!. 커널은이를 사용하여 인터프리터를 시작해야합니다.


2
나는 항상 그것이 커널이 아니라 쉘의 기능이라고 가정했다. 오늘 새로운 것을 배웠습니다.
보트 코더

1
@boatcoder-관심이 있기 때문에 Linux 소스 코드가 처리하는 위치에 대한 링크를 추가했습니다.
날씬한
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.