Ist gawk normalerweise in / bin oder / usr / bin? Ich würde mitgehen, #!/usr/bin/env gawk
aber dann kann ich keine Argumente verwenden. Im Moment benutze ich #!/bin/gawk -f
. Das Skript ist sehr lang und enthält viele einfache Anführungszeichen und funktioniert mit stdin.
Das GNU Awk-Handbuch enthält Abschnitt 1.1.4 Ausführbare awk-Programme, in denen in seinem Beispiel #! / Bin / awk verwendet wird.
Beachten Sie, dass auf vielen Systemen
awk
in/usr/bin
statt statt in gefunden werden kann/bin
. Vorbehalt Emptor.
Was machen die meisten Leute? Ich habe gelesen, dass sed angeblich in / bin standardisiert ist, während Perl angeblich in / usr / bin standardisiert ist (dieselbe Seite wie sed link, aber ich kann keinen dritten Link für diesen Beitrag erstellen). Was ist mit awk / gawk? Weiß jemand, was häufiger oder beliebter ist?
-f
? Ist das nicht/bin/gawk
genug Auch dies relevant sein könnte.Antworten:
Shebang sollte nicht so flexibel sein . Es kann Fälle geben, in denen ein zweiter Parameter funktioniert . Ich denke, FreeBSD ist einer davon.
Gawk und die meisten Dienstprogramme, die mit dem Betriebssystem geliefert werden, werden voraussichtlich verfügbar sein
/usr/bin/
.In den älteren UNIX-Tagen war es üblich,
/usr/
über NFS oder ein weniger teures Medium zu mounten, um lokalen Speicherplatz und Kosten pro Workstation zu sparen./bin/
sollte alles haben, was zum Booten im Einzelbenutzermodus benötigt wird . Da/usr/
es nicht auf einem zuverlässigen Medium installiert war,/bin/
enthielt es genügend Dienstprogramme, um es für die allgemeine Verwaltung und Fehlerbehebung benutzerfreundlich genug zu machen.Dies wurde ursprünglich unter Linux vererbt, aber da Speicherplatz kein Problem mehr darstellt und sich in den meisten Fällen
/usr/
im Root-Dateisystem befindet, besteht der aktuelle Trend darin, alles zu verschieben/usr/bin
(zumindest in der Linux-Welt). Daher wird erwartet, dass die meisten von einer Distribution installierten Dienstprogramme dort zu finden sind. Selbst die grundlegenden Werkzeuge, wiecp
,rm
,ls
usw. (na ja, noch nicht).In Bezug auf die Shebang-Wahl. Traditionell müssen Administratoren oder Benutzer dies entsprechend ihrer Umgebung bearbeiten. Für alle Entwickler, in anderen Leuten Systeme kennen, könnte der Dolmetscher überall im Dateisystem (zB
/usr/local/bin
,/opt/gawk-4.0.1/bin
). Ordnungsgemäß gepackte Skripte (rpm, deb usw.) sind entweder von einem Distributionspaket abhängig (dh der Interpreter hat einen bekannten Speicherort) oder von einem Konfigurationsskript, das den richtigen Hashbang während der Installation einrichtet.quelle
Wenn Sie dem Befehl keine Argumente übergeben müssen,
#!/usr/bin/env gawk
ist dies der richtige Weg. Viele Kernel (einschließlich Linux) akzeptieren jedoch nur ein einziges Argument für Shebang-Programme.Andernfalls können Sie ein Polyglot- Programm erstellen , das sowohl ein Shell-Wrapper als auch das awk-Skript ist. Hier ist eine für awk.
Shell-Analyse:
true + /;
- der Befehltrue
(der nichts tut) mit zwei inerten Argumenten+
und/
.gawk
. Dies kann jedes Shell-Snippet sein, das keine Zeilenumbrüche enthält und in dem Schrägstriche geschrieben sind\/
(die Shell hat nichts dagegen, außer in Anführungszeichen).Der Aufruf wird verwendet
exec
, um die Shell durch gawk zu ersetzen, anstatt gawk als Unterprozess auszuführen.exit;
- Verlassen Sie die Schale, falls kein Gawk gefunden wurde. Alles, was danach passiert, wird ignoriert, außer dass es eine gültige Shell-Syntax sein sollte, falls die Shell versucht, die gesamte Zeile zu analysieren, bevor sie mit der Ausführung beginnt.Awk-Analyse:
true + /REGEX/
- ein Zustand.true
ist eine undefinierte Variable, daher ist ihr numerischer Wert 0, nicht dass es darauf ankommt.{}
- Wenn diese Bedingung erfüllt ist, tun Sie nichts.quelle
Gilles 'Lösungsvorschlag ist in der Tat ein sehr guter Ansatz (endlich den Ruf, in seinem Beitrag abzustimmen :)).
Soweit ich den
exec
Befehl verstehe , macht er dasexit
Recht danach auf jeden Fall unnötig, tatsächlich nicht erreichbar, da der Shell-Prozess durch ersetzt wirdawk
.Um dem
awk
Skript den Zugriff auf seine Aufrufparameter zu ermöglichen, würde ich außerdem einige Änderungen an der vorgeschlagenen Lösung vorschlagen:Das
-a "$0"
ermöglicht dem Skript den Zugriff auf seinen Aufrufnamen, andernfalls erhält es immer einawk
oder,gawk
wenn auf dieARGV[0]
Variable zugegriffen wird. In ähnlicher Weise"$@"
ermöglicht das Skript dem Zugriff auf die verbleibenden Parameter imARGV[1...N]
Array, und das--
vorhergehende ermöglicht es dem Skript,-<something>
Argumente zu empfangen , ohne dass Gawk sie interpretiert.Eine Sache, an die Sie sich erinnern / die Sie berücksichtigen sollten, ist das Hinzufügen einer
exit(0);
Anweisung am Ende desBEGIN { ... }
Blocks desawk
Skriptprogramms. Andernfallsawk
werden alle Parameter bedroht, die als Eingabedateien an das Skript übergeben werden. (Bitte beachten Sie, dass es überhaupt nichts mit derexit
Anweisung zu tun hat, die wir aus dertrue + ...
Zeile entfernt haben. Dies war eine nicht erreichbare Shell-Anweisung, während sich dieser vorgeschlagene Exit im awk-Code befindet.)quelle
exit(0)
war sehr nützlich! Für Macos-Benutzer gilt Folgendes: Ein guter tragbarer awk shebang ist nicht leicht zu finden.