Есть ли команда для запуска скрипта в соответствии со строкой shebang?

Если я хочу выполнить bash-скрипт, для которого не установлены разрешения на выполнение, я могу сделать:

bash script.sh

Что я должен использовать вместо bash, если скрипт не исполняется и я не знаю правильного переводчика? Есть ли команда, которая ищет интерпретатор из строки shebang и выполняет сценарий вместе с ним?

46
задан 17 November 2016 в 13:10

3 ответа

Да. Это называют 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 :

, Если #! строка не содержит слово "perl", ни слово "indir", программа, названная в честь эти #!, выполнена вместо интерпретатора Perl. Это немного причудливо, но это помогает людям на машинах, которые не делают #!, потому что они могут сказать программе, что их SHELL является/usr/bin/perl, и Perl затем отправит программу корректному интерпретатору для них.

67
ответ дан 17 November 2016 в 23:10

Сценарии не обязательно имеют хижину

Если скрипт был запущен от интерпретатора, Вы не можете быть уверены, что он имеет хижину вообще. Для скриптов, запущенных от интерпретатора, не нужна хижина при вызове интерпретатора для выполнения кода.

Ответ поэтому не, нет никакой команды, которая узнает наверняка, что является языком (интерпретатор) для запущения скрипта с. Можно однако всегда смотреть в сценарии и видеть, имеет ли он хижину для обнаружения.

Правила короче говоря:

  1. Когда Вы запускаете скрипт, называние интерпретатора всегда отвергает возможные хижины, исполняемый файл или нет, хижину или нет.
  2. Если не исполняемый файл и выполнение от интерпретатора, для сценария не нужна никакая хижина.
  3. Если скрипт запущен, не называя интерпретатор сначала, ему нужна (и использование) хижина для обнаружения, какой интерпретатор звонить, и это должен быть исполняемый файл, чтобы иметь "разрешение" назвать интерпретатором от его хижины.

Если сценарий не имеет никакой хижины однако, существует не (прямое*) информация в сценарии для сообщения что интерпретатор использовать.

Сказав это

Вы могли, конечно, всегда писать сценарий обертки, чтобы попытаться узнать, имеет ли сценарий хижину, и считайте интерпретатор из этого, впоследствии выполните его от найденного интерпретатора.

Пример

#!/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
    

    вызовы (протестировали) корректный интерпретатор на моем неисполняемом файле python и bash сценарии.

Объяснение

  • Сценарий просто читает первую строку сценария, удаляет #! и использование остальные для вызова интерпретатора.
  • Если это не назовет допустимый интерпретатор, то это повысит любого a PermissionError или a FileNotFoundError.

Примечание:

Расширение (.sh, .py и т.д.), не играет роли вообще в определении соответствующего интерпретатора на Linux.


(*It, конечно, возможно разработать "умное" предположение - алгоритм для определения синтаксиса из кода.)

25
ответ дан 17 November 2016 в 23:10

Можно достигнуть этого со сценарием как это:

#!/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

я рекомендую против выполнения этого. Полномочия там по причине. Это - программа для того, чтобы ниспровергать полномочия.

Примечание, что обработка хижины ядро функция (в исходном коде Linux - fs/binfmt_script.c ). Существенно процесс, вызывающий сценарий непосредственно, не знает о #! - ядро использует его, чтобы решить, что он должен запустить интерпретатор.

6
ответ дан 17 November 2016 в 23:10

Другие вопросы по тегам:

Похожие вопросы: