Verwandte: Welcher Shell-Interpreter führt ein Skript ohne Schebang aus?
Das Skript hat kein shebang / hashbang / #!
line, einfach weil ein doppelter Gedankenstrich nicht ist #!
.
Das Skript wird jedoch von einer Shell ausgeführt (siehe oben verlinkte Fragen und Antworten). Wenn in dieser Shell -
ein gültiges Zeichen in einem Funktionsnamen ist, deklariert die Zeile eine Shell-Funktion, die aufgerufen --
wird und nichts tut (nun, sie wird ausgeführt :
, was nix tut ) und was nie aufgerufen wird.
Die Funktion in der gebräuchlicheren mehrzeiligen Notation (nur um zu verdeutlichen, wie sie aussieht, da ihr seltsamer Name die Tatsache verdeckt, dass es sich tatsächlich um eine Funktion handelt):
-- () {
:
}
Der einzige Zweck der Funktionsdefinition besteht darin, eine Zeile zu haben, die in einem Shell-Skript gültig ist und gleichzeitig einen gültigen SQL-Befehl (einen Kommentar) enthält. Diese Art von Code wird als Polyglot bezeichnet .
Nachdem die falsche Shell-Funktion deklariert wurde, ersetzt das Skript, wenn es von einem Shell-Skript-Interpreter ausgeführt wird exec
, die aktuelle Shell durch den aus der Ausführung resultierenden Prozess. Dies entspricht der db2 -txf "$0"
Verwendung db2 -txf
des Pfadnamens des Skripts über die Befehlszeile.
Dieser Trick würde wahrscheinlich nicht zuverlässig auf Systemen funktionieren, auf denen dash
oder auf denen andere ash
Shells, yash
die Bourne-Shell, ksh88
oder ksh93
verwendet werden /bin/sh
, da diese Shell keine Funktionen akzeptiert, deren Name Bindestriche enthält.
Auch verwandt:
Ich nehme an, dass das Folgende auch funktionieren würde (nicht wirklich getestet):
--() { exec db2 -txf "$0"; }; --
Wie @Kusalananda bereits sagte, ist dieser Trick gebrochen und funktioniert nicht in allen Shells.
Hier ist meine Meinung dazu:
Der erste Befehl sollte auch dann fehlschlagen, wenn eine Datei / ein Verzeichnis mit dem Namen
--
im aktuellen Verzeichnis vorhanden ist und alle Fehler vom Befehl2>/dev/null
; Die Shell fährt dann mit dem zweiten Befehl fort, demexec
.quelle
ENOEXEC
wenn Sie dies versuchen. Führen Sie das Skript unter aus, umstrace
zu sehen, was ich meine.exec()
es nicht funktioniert. "Wenn die execl () - Funktion aufgrund eines Fehlers, der dem [ENOEXEC] -Fehler entspricht, fehlschlägt, muss die Shell einen Befehl ausführen, der dem Aufrufen einer Shell mit dem Befehlsnamen als erstem Operanden entspricht, ..." (siehe pubs.opengroup) .org / onlinepubs / 9699919799.2018edition / utilities /… )exec()
es direkt von etwas anderem als einer Shell ausführst . Aber was wäre das für ein Fall? Möglicherweise möchten Sie das Skript ausführencron
, aber ich denke, es wird sowieso alles durch eine Shell ausgeführt, und selbst wenn dies nicht derdb2 -txf /path/to/script
Fall ist, ist es in diesem Fall einfach, es einfach zu formulieren , da Sie es nur einmal ausführen müssen. Die Kurzarbeit ist vor allem in einer interaktiven Shell nützlich. Sicher ist jedoch, dass ein separates Wrapper-Skript möglicherweise robuster ist.echo 'int main(int c,char**a){execvp(a[1],a+1);}' | cc -include unistd.h -xc -; echo echo yeah > a.sh; chmod 755 a.sh; ./a.out ./a.sh; PATH=`pwd` ./a.out a.sh