Ich möchte ein Gawk- Skript mit --re-interval
einem Shebang ausführen . Der "naive" Ansatz von
#!/usr/bin/gawk --re-interval -f
... awk script goes here
funktioniert nicht, da gawk mit dem ersten Argument aufgerufen wird "--re-interval -f"
(nicht um das Leerzeichen aufgeteilt), das es nicht versteht. Gibt es dafür eine Problemumgehung?
Natürlich können Sie gawk entweder nicht direkt aufrufen, sondern in ein Shell-Skript einbinden, das das erste Argument aufteilt, oder ein Shell-Skript erstellen, das dann gawk aufruft und das Skript in eine andere Datei einfügt, aber ich habe mich gefragt, ob es eine Möglichkeit gibt, dies zu tun dies innerhalb einer Datei.
Das Verhalten von Shebang-Linien unterscheidet sich von System zu System - zumindest in Cygwin werden die Argumente nicht durch Leerzeichen aufgeteilt. Mir ist nur wichtig, wie es auf einem System gemacht wird, das sich so verhält. Das Skript soll nicht portabel sein.
--re-interval
es nicht mehr benötigt (siehe [ gnu.org/software/gawk/manual/… ).Antworten:
Dies scheint bei mir mit (g) awk zu funktionieren.
Beachten Sie die
#!
Läufe/bin/sh
, sodass dieses Skript zuerst als Shell-Skript interpretiert wird.Zuerst habe ich es einfach versucht
"exec" "/usr/bin/gawk" "--re-interval" "-f" "$0" "$@"
, aber awk hat das als Befehl behandelt und jede Eingabezeile bedingungslos ausgedruckt. Deshalb habe ich das eingegebenarbitrary_long_name==0
- es soll die ganze Zeit scheitern. Sie könnten es durch eine Kauderwelschschnur ersetzen. Grundsätzlich suchte ich nach einer falschen Bedingung in awk, die das Shell-Skript nicht beeinträchtigen würde.Im Shell-Skript
arbitrary_long_name==0
definiert das eine aufgerufene Variablearbitrary_long_name
und setzt sie gleich=0
.quelle
bash
an oder funktioniert es mit jedem POSIXsh
? Und ich benutze es nichtawk
oft, daher bin ich mir nicht sicher, ob mein Trick in der zweiten Zeile ein guter Weg ist, umawk
das Ignorieren der Zeile zu erzwingen .arbitrary_long_name
nicht mit einer im realen awk-Programm verwendeten Variablen kollidiert, kann ich kein Problem erkennen. Fehlt mir etwas?#!/bin/sh -
Option#!/bin/sh
, um das Skript vor möglicherweise gefährlichem Fehlverhalten zu schützen, wenn es mit einem nullten Argument aufgerufen wird, das-
das erste Zeichen enthält. Dies kann versehentlich in Programmiersprachen wie C passieren, wo es leicht zu Versehen kommt, wenn man vergisst, den aufgerufenen Programmnamen als Teil des Argumentarrays anexecve
ähnliche Funktionen zu übergeben, und wenn die Leute gewöhnlich vergessen, sich dagegen zu schützen, kann dies auch passieren Dies ist der letzte Schritt in einer böswillig ausnutzbaren Sicherheitsanfälligkeit, mit der ein Angreifer eine interaktive Shell erhalten kann.Die Shebang-Linie wurde nie als Teil von POSIX, SUS, LSB oder einer anderen Spezifikation spezifiziert. AFAIK, es wurde nicht einmal richtig dokumentiert.
Es besteht ein grober Konsens darüber, was es tut: Nehmen Sie alles zwischen das
!
und das\n
undexec
es. Die Annahme ist, dass alles zwischen dem!
und dem\n
ein vollständiger absoluter Pfad zum Interpreten ist. Es besteht kein Konsens darüber, was passiert, wenn es Leerzeichen enthält.Zum Glück scheinen 1. und 4. ausgestorben zu sein, aber 3. ist ziemlich weit verbreitet, sodass Sie sich einfach nicht darauf verlassen können, mehr als ein Argument vorbringen zu können.
Und da die Lage der Befehle ist auch in POSIX oder SUS nicht angegeben ist , verwenden Sie in der Regel , dass einzelne Argument, indem sie die ausführbaren vorbei Namen zu ,
env
so dass es die ausführbare Standort bestimmen können; z.B:[Offensichtlich nimmt dies immer noch einen bestimmten Weg an
env
, aber es gibt nur sehr wenige Systeme, in denen es lebt/bin
, so dass dies im Allgemeinen sicher ist. Der Standort vonenv
ist viel standardisierter als der Standort vongawk
oder noch schlimmer etwas wiepython
oderruby
oderspidermonkey
.]Das bedeutet, dass Sie überhaupt keine Argumente verwenden können .
quelle
-S
Schalter, der hier hilft, aber er ist unter meinem Linux nicht vorhandenenv
, und ich vermute, dass er auch auf gygwin nicht verfügbar ist. @hstoerr, andere Benutzer mit unterschiedlichen Situationen lesen Ihre Fragen möglicherweise später. Daher sind tragbare Antworten im Allgemeinen vorzuziehen, auch wenn Sie jetzt keine Portabilität benötigen.#!/bin/sh
und enthält/usr/bin/env gawk --re-interval -f my-script.awk
. Ist das korrekt?#!
selbst nicht portabel sind. Beispielsweise erkennt Windows diese Konvention "nativ" überhaupt nicht. Unter Unix ist traditionell ein Ein-Argument-Knall erforderlich, um dies zu tun#!/usr/bin/awk -f
.#!/usr/bin/env ruby
oder dergleichen.Obwohl nicht gerade portabel, können Sie ab Coreutils 8.30 und gemäß der Dokumentation Folgendes verwenden:
So gegeben:
Sie erhalten:
und falls Sie neugierig sind,
showargs
ist:Ursprüngliche Antwort hier .
quelle
Ich bin auf dasselbe Problem gestoßen, ohne offensichtliche Lösung, da die Leerzeichen in einem Shebang behandelt werden (zumindest unter Linux).
Sie können jedoch mehrere Optionen in einem Shebang übergeben, sofern es sich um kurze Optionen handelt und diese verkettet werden können (nach GNU-Art).
Zum Beispiel können Sie nicht haben
aber du kannst haben
Dies funktioniert natürlich nur, wenn die Optionen kurze Entsprechungen haben und keine Argumente enthalten.
quelle
Unter Cygwin und Linux wird alles nach dem Pfad des Shebang als ein Argument in das Programm analysiert.
Es ist möglich, dies zu umgehen, indem Sie ein anderes
awk
Skript im Shebang verwenden:Dies wird
{system("/usr/bin/gawk --re-interval -f " FILENAME); exit}
in awk ausgeführt.Und dies wird
/usr/bin/gawk --re-interval -f path/to/your/script.awk
in Ihrer System-Shell ausgeführt.quelle
Der obige Shell Shebang Trick ist tragbarer als
/usr/bin/env
.quelle
python
, aber bei dieser Frage geht es umawk
.Im Gawk-Handbuch (http://www.gnu.org/manual/gawk/gawk.html) wird am Ende von Abschnitt 1.14 darauf hingewiesen, dass Sie nur ein einziges Argument verwenden sollten, wenn Sie Gawk von einer Shebang-Linie aus ausführen. Es heißt, dass das Betriebssystem alles nach dem Weg zum Gaffen als ein einziges Argument behandeln wird. Vielleicht gibt es eine andere Möglichkeit, die
--re-interval
Option anzugeben ? Vielleicht kann Ihr Skript auf Ihre Shell in der Shebang-Zeile verweisen,gawk
als Befehl ausgeführt werden und den Text Ihres Skripts als "Hier-Dokument" einfügen.quelle
gawk
, aber Sie können möglicherweise immer noch etwas über stderr einleiten (dh stdout zu stderr umleiten, bevor Sie in dieses Skript weiterleiten). Ich habe das noch nie versucht, aber solange der erste Prozess auf stderr nichts aussendet, könnte es funktionieren. Sie können auch eine Named Pipe erstellen ( linuxjournal.com/content/using-named-pipes-fifos-bash ), wenn Sie sicherstellen möchten, dass nichts anderes sie verwendet.Warum nicht
bash
und sichgawk
selbst verwenden, um Shebang zu überspringen, das Skript zu lesen und es als Datei an eine zweite Instanz von zu übergebengawk [--with-whatever-number-of-params-you-need]
?(-das gleiche könnte natürlich auch mit zB
sed
oder erreicht werdentail
, aber ich denke, es gibt eine Art von Schönheit, die nur vonbash
und von sichgawk
selbst abhängt;)quelle
Nur zum Spaß: Es gibt die folgende ziemlich seltsame Lösung, die stdin und das Programm über die Dateideskriptoren 3 und 4 umleitet. Sie können auch eine temporäre Datei für das Skript erstellen.
Eines ist daran ärgerlich: Die Shell führt eine variable Erweiterung des Skripts durch, sodass Sie jedes $ (wie in der zweiten Zeile des Skripts angegeben) und wahrscheinlich mehr angeben müssen.
quelle
Für eine tragbare Lösung verwenden ,
awk
anstattgawk
, rufen Sie den Standard - Bourne - Shell (/bin/sh
) mit Ihrem shebang, und rufen Sieawk
das Programm auf der Kommandozeile vorbei als hier direkt dokumentieren , anstatt über stdin:Hinweis: kein
-f
Argument zuawk
. Damitstdin
stehenawk
Eingaben zum Lesen zur Verfügung. Angenommen, Sie habengawk
und auf Ihrem installiertPATH
, erreicht dies alles, was Sie meiner Meinung nach mit Ihrem ursprünglichen Beispiel versucht haben (vorausgesetzt, Sie wollten, dass der Dateiinhalt das awk-Skript und nicht die Eingabe ist, was Ihr Shebang-Ansatz meiner Meinung nach behandelt hätte ).quelle