Если я хочу выполнить bash-скрипт, для которого не установлены разрешения на выполнение, я могу сделать:
bash script.sh
Что я должен использовать вместо bash
, если скрипт не исполняется и я не знаю правильного переводчика? Есть ли команда, которая ищет интерпретатор из строки shebang и выполняет сценарий вместе с ним?
Да. Это называют 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 затем отправит программу корректному интерпретатору для них.
Если скрипт был запущен от интерпретатора, Вы не можете быть уверены, что он имеет хижину вообще. Для скриптов, запущенных от интерпретатора, не нужна хижина при вызове интерпретатора для выполнения кода.
Ответ поэтому не, нет никакой команды, которая узнает наверняка, что является языком (интерпретатор) для запущения скрипта с. Можно однако всегда смотреть в сценарии и видеть, имеет ли он хижину для обнаружения.
Правила короче говоря:
Если сценарий не имеет никакой хижины однако, существует не (прямое*) информация в сценарии для сообщения что интерпретатор использовать.
Вы могли, конечно, всегда писать сценарий обертки, чтобы попытаться узнать, имеет ли сценарий хижину, и считайте интерпретатор из этого, впоследствии выполните его от найденного интерпретатора.
Пример
#!/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
сценарии.
#!
и использование остальные для вызова интерпретатора. PermissionError
или a FileNotFoundError
.Расширение (.sh
, .py
и т.д.), не играет роли вообще в определении соответствующего интерпретатора на Linux.
(*It, конечно, возможно разработать "умное" предположение - алгоритм для определения синтаксиса из кода.)
Можно достигнуть этого со сценарием как это:
#!/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
). Существенно процесс, вызывающий сценарий непосредственно, не знает о #!
- ядро использует его, чтобы решить, что он должен запустить интерпретатор.