Powiązane: Który interpreter powłoki uruchamia skrypt bez shebang?
Skrypt nie ma #!
linii shebang / hashbang / line, po prostu dlatego, że nie ma podwójnego myślnika #!
.
Jednak skrypt zostanie wykonany przez powłokę (patrz wyżej powiązane pytanie i odpowiedzi), aw tej powłoce, jeśli -
jest poprawnym znakiem w nazwie funkcji, linia deklaruje wywołaną funkcję powłoki --
, która nic nie robi (cóż, działa :
, który nic nie robi ) i który nigdy nie jest nazywany.
Funkcja, w bardziej powszechnej notacji wieloliniowej (aby po prostu pokazać, jak to wygląda, ponieważ jej dziwna nazwa niejasno tłumi fakt, że w rzeczywistości jest funkcją):
-- () {
:
}
Jedynym celem definicji funkcji jest posiadanie wiersza, który jest poprawny w skrypcie powłoki, a jednocześnie poprawne polecenie SQL (komentarz). Ten rodzaj kodu nazywa się poliglotą .
Po zadeklarowaniu fałszywej funkcji powłoki skrypt wykonywany przez interpreter skryptu powłoki exec
zastępuje bieżącą powłokę procesem wynikającym z uruchomienia db2 -txf "$0"
, który byłby taki sam, jak użycie db2 -txf
nazwy ścieżki skryptu z wiersza poleceń.
Ta sztuczka prawdopodobnie nie działałaby niezawodnie w systemach, w których dash
lub ash
powłoki oparte na innych powłokach, yash
powłoka Bourne'a ksh88
lub ksh93
jest używana jako /bin/sh
, ponieważ powłoki te nie akceptują funkcji, których nazwa zawiera myślniki.
Powiązane również:
Przypuszczam, że następujące elementy również by działały (nie tak naprawdę przetestowane):
--() { exec db2 -txf "$0"; }; --
Jak już powiedział @Kusalananda, ta sztuczka jest zepsuta i nie będzie działać we wszystkich powłokach.
Oto moje podejście do robienia tego przenośnie:
Pierwsze polecenie powinno zakończyć się niepowodzeniem, nawet jeśli nazwa pliku / katalogu
--
istnieje w bieżącym katalogu, a wszelkie błędy zostaną zamknięte przez2>/dev/null
; powłoka będzie postępować z drugim komendzieexec
.źródło
ENOEXEC
jeśli spróbujesz. Spróbuj uruchomić skrypt pod,strace
aby zobaczyć, co mam na myśli.exec()
na nim nie działa. „Jeśli funkcja execl () zawiedzie z powodu błędu równoważnego z błędem [ENOEXEC], powłoka wykonuje polecenie równoważne z wywołaniem powłoki z nazwą polecenia jako pierwszym operandem, ...” (patrz pubs.opengroup .org / onlinepubs / 9699919799.2018edition / utilities /… )exec()
bezpośrednio z innej powłoki. Ale jaka byłaby ta sprawa? Możesz chcieć uruchomić skryptcron
lub coś takiego, ale myślę, że i tak wszystko przepuszcza przez powłokę, a nawet jeśli nie, łatwo to przeliterowaćdb2 -txf /path/to/script
w tym przypadku, ponieważ musisz to zrobić tylko raz. Praca stenograficzna jest najbardziej przydatna w interaktywnej powłoce. Ale oczywiście osobny skrypt opakowania może być bardziej niezawodny.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