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

Вот простой скрипт python, который выпускает LXC dnsmasq lease. Вы можете запустить его с хост-компьютера или подделать его из другого контейнера - да, что работает!:

#!/usr/bin/env python
from scapy.all import *
conf.checkIPaddr=False
leaseMAC = '00:16:3e:11:71:b0' #container MAC here
releaseIP='10.0.3.33' #container IP here
serverIP='10.0.3.1'
hostname='container-name-here'
rawMAC = leaseMAC.replace(':','').decode('hex')
send(IP(dst=serverIP) / \
     UDP(sport=68,dport=67) / \
     BOOTP(chaddr=rawMAC, ciaddr=releaseIP, xid=RandInt()) / \
     DHCP(options=[('message-type','release'),('server_id',serverIP),('hostname',hostname), ('end')]))

Перцепция для выше - это scapy python library:

pip install scapy

После запуска вы должны увидеть в системном журнале что-то вроде:

dnsmasq-dhcp[3242]: DHCPRELEASE(lxcbr0) 10.0.3.33 00:16:3e:11:71:b0 container-name-here

Чтобы подтвердить, просто проверьте, удалена ли запись из /var/lib/misc/dnsmasq.lxcbr0.leases. Сам контейнер будет поддерживать IP-адрес, поэтому его следует остановить до запуска любого нового контейнера, который должен повторно использовать IP.

1
задан 17 November 2016 в 14:10

2 ответа

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

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

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

Короче говоря:

Когда вы запускаете скрипт, вызов интерпретатора всегда перекрывает возможные shebangs, исполняемый файл или нет, shebang или нет. Если он не исполняется и запускается из интерпретатора, сценарий не нуждается ни в каком shebang. Если сценарий запускается без вызова интерпретатора сначала, ему нужно (и использует) shebang, чтобы узнать, какой интерпретатор должен позвонить, и он должен быть исполняемым, чтобы иметь «разрешение» называть интерпретатора из его shebang.

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

Сказав, что

Вы, конечно, всегда можете написать сценарий оболочки на всех , чтобы узнать, есть ли скрипт в 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
вызывает (проверяет) правильный интерпретатор на моих невыполняемых сценариях python и bash.

Объяснение

Сохраните его как tryrun в $PATH (например, ~/bin, создайте каталог, если он не существует, выйдите из системы и зайдите в него) сделать его исполняемым. Затем:
tryrun /path/to/nonexecutablescript
вызывает (проверяет) правильный интерпретатор на моих невыполняемых сценариях python и bash.
Если он не может вызвать действительный интерпретатор, он поднимет либо PermissionError, либо FileNotFoundError.

Примечание

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

(* Конечно, можно разработать «умный» алгоритм угадывания, чтобы определить синтаксис кода.)

25
ответ дан 23 May 2018 в 04:08
  • 1
    ОК, поэтому это означает, что хотя Linux имеет извлечение shebang, реализованное где-то (чтобы он мог выбрать правильный интерпретатор для исполняемых srcipts), он не предоставляется как стандартная стандартная команда. – Aivar 17 November 2016 в 16:01
  • 2
    @Aivar, извлекающий shebang, не является проблемой, но запуск кода без него вполне возможен. – Jacob Vlijm 17 November 2016 в 17:46
  • 3
    @ Эйвар, я понимаю, что вы имеете в виду. Если скрипт является исполняемым и запускается без языка в команде, сценарий вызывает интерпретатор, а не наоборот. – Jacob Vlijm 17 November 2016 в 17:55
  • 4
    @JacobVlijm Я бы не сказал, что «сценарий вызывает интерпретатор», более похожим на «ядро Linux, которое берет строку shebang для выяснения, какой интерпретатор должен вызывать при выполнении сценария». – Paŭlo Ebermann 18 November 2016 в 00:37
  • 5
    @ PaŭloEbermann Спасибо! Конечно, конечно. Ядро позаботится обо всей процедуре в любом случае, но в переносном смысле, и я думаю, что лучше для понимания, так сказать, сценарий «разрешен». позаботиться о том, какой интерпретатор должен позвонить (и на самом деле сделать это). Не уверен в формулировке, но я бы хотел описать ее так, как если бы инициатива была в скрипте, а ядро ​​действительно выполняло эту работу. – Jacob Vlijm 18 November 2016 в 00:47

Вы можете добиться этого с помощью скрипта следующим образом:

#!/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). В основном процесс, вызывающий скрипт напрямую, не знает о #! - ядро ​​использует его для разработки, чтобы запустить интерпретатор.

6
ответ дан 23 May 2018 в 04:08
  • 1
    Я всегда считал, что это функция оболочки, а не ядро. Сегодня узнал что-то новое. – boatcoder 19 November 2016 в 00:54
  • 2
    @boatcoder. Поскольку вам интересно, добавлена ​​ссылка на исходный код Linux. – slim 19 November 2016 в 20:50

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

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