Вот простой скрипт 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.
. Если скрипт был запущен из интерпретатора, вы не можете быть уверены, что он имеет 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/to/nonexecutablescript
вызывает (проверяет) правильный интерпретатор на моих невыполняемых сценариях python и bash. Если он не может вызвать действительный интерпретатор, он поднимет либо PermissionError, либо FileNotFoundError. Расширение (.sh, .py и т. д.) не играет никакой роли в определении соответствующего интерпретатора в Linux.
(* Конечно, можно разработать «умный» алгоритм угадывания, чтобы определить синтаксис кода.)
Вы можете добиться этого с помощью скрипта следующим образом:
#!/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). В основном процесс, вызывающий скрипт напрямую, не знает о #! - ядро использует его для разработки, чтобы запустить интерпретатор.