Wie kann man ein Skript schreiben, das Eingaben von einem Dateinamenargument oder von stdin akzeptiert?
Zum Beispiel könnten Sie less
diesen Weg benutzen . man kann less filename
und gleichwertig ausführen cat filename | less
.
gibt es einen einfachen "out of the box" Weg, dies zu tun? Oder muss ich das Rad neu erfinden und ein wenig Logik in das Skript schreiben?
command-line
bash
stdin
Gilad hoch
quelle
quelle
Antworten:
Wenn das Dateiargument das erste Argument für Ihr Skript ist, prüfen Sie, ob es ein Argument (
$1
) und eine Datei gibt. Sonst lese die Eingabe von stdin -Ihr Skript könnte also etwa Folgendes enthalten:
zB dann kannst du das script gerne aufrufen
oder
Bearbeiten Eine Erklärung des Skripts:
[ $# -ge 1 -a -f "$1" ]
- Wenn mindestens ein Befehlszeilenargument ($# -ge 1
) UND (-a Operator) das erste Argument eine Datei ist (-f testet, ob "$ 1" eine Datei ist), ist das Testergebnis wahr.&&
ist der Shell-logische AND-Operator. Wenn der Test wahr ist, wird die Datei zugewieseninput="$1"
undcat $input
ausgegeben.||
ist der logische ODER-Operator der Shell. Wenn der Test falsch ist, werden die folgenden Befehle||
analysiert. Eingang ist mit "-" belegt. Der Befehlcat -
liest von der Tastatur.Zusammenfassend wird, wenn das Skriptargument bereitgestellt wird und es sich um eine Datei handelt, die Variableneingabe dem Dateinamen zugewiesen. Wenn es kein gültiges Argument gibt, liest cat von der Tastatur.
quelle
&& input="$1" || input="-"
und warum ist es außerhalb destest
Betreibers?$@
)?read
Liest von der Standardeingabe. Das Umleiten von file (./script <someinput
) oder through pipe (dosomething | ./script
) führt nicht zu einer anderen Funktionsweise.Alles, was Sie tun müssen, ist, alle Zeilen in der Eingabe zu durchlaufen (und es unterscheidet sich nicht von der Iteration über die Zeilen in der Datei).
(Beispielcode, verarbeitet nur eine Zeile)
Gibt die erste Zeile Ihrer Standardeingabe wieder (entweder durch
<
oder|
).quelle
Sie erwähnen nicht, welche Shell Sie verwenden möchten, also nehme ich bash an, obwohl dies bei allen Shells ziemlich übliche Dinge sind.
Datei Argumente
Auf Argumente kann über die Variablen zugegriffen werden
$1
-$n
($0
gibt den Befehl zurück, der zum Ausführen des Programms verwendet wird). Angenommen, ich habe ein Skript, das nurcat
n Dateien mit einem Trennzeichen dazwischen enthält:In diesem Fall übergeben wir einen Dateinamen an cat. Wenn Sie jedoch die Daten in der Datei transformieren möchten (ohne sie explizit zu schreiben und neu zu schreiben), können Sie den Dateiinhalt auch in einer Variablen speichern:
Lesen Sie von stdin
Was das Lesen von stdin
read
angeht, haben die meisten Shells einen ziemlich standardmäßigen Aufbau, obwohl es (zumindest) Unterschiede in der Art und Weise gibt, wie Eingabeaufforderungen angegeben werden.Die Manpage von Bash builtins hat eine ziemlich knappe Erklärung
read
, aber ich bevorzuge die Seite von Bash Hackers .Einfach:
Mehrere Variablen
Um mehrere Variablen festzulegen, geben Sie einfach mehrere Parameternamen an
read
:read
Setzt dann ein Wort von stdin in jede Variable, wobei alle verbleibenden Wörter in die letzte Variable geschrieben werden.Wenn weniger Wörter als Variablen eingegeben werden, sind die verbleibenden Variablen leer (auch wenn sie zuvor festgelegt wurden):
Eingabeaufforderungen
Ich benutze
-p
flag oft für eine Eingabeaufforderung:Hinweis: ZSH und KSH (und möglicherweise auch andere) verwenden für Eingabeaufforderungen eine andere Syntax:
Standardwerte
Das ist kein wirklicher
read
Trick, aber ich benutze ihn oft in Verbindung mitread
. Zum Beispiel:Wenn die Variable (reply) vorhanden ist, geben Sie sich selbst zurück. Wenn sie leer ist, geben Sie den folgenden Parameter zurück ("N").
quelle
Der einfachste Weg ist, stdin selbst umzuleiten:
Oder wenn Sie die knappere Form bevorzugen:
Jetzt kann der Rest Ihres Skripts nur noch von stdin lesen. Natürlich können Sie die Position des Dateinamens auch mit erweiterten Optionen analysieren, anstatt sie fest zu codieren
"$1"
.quelle
exec
Ich werde versuchen, das Argument als Befehl auszuführen, was wir hier nicht wollen.if [ "$1" ] ; then exec < "$1" ; fi
in einem Testskript kopiert und es wird eine Fehlermeldung ausgegeben, da der Befehl unbekannt ist. Gleiches gilt für die knappe Form.benutze (oder verkette) etwas anderes, das sich bereits so verhält, und benutze
"$@"
Angenommen, ich möchte ein Tool schreiben, das Leerzeichen in Text durch Tabulatoren ersetzt
tr
ist der naheliegendste Weg, dies zu tun, aber er akzeptiert nur stdin, also müssen wir verketten voncat
:Für ein Beispiel, in dem sich das verwendete Tool bereits so verhält, könnten wir dies
sed
stattdessen mit neu implementieren :quelle
Sie können auch:
Weitere nützliche Tricks zum Ersetzen von Parametern in Bash finden Sie hier .
quelle
uglifyjs < /dev/stdin
und es funktioniert wunderbar!Sie können es auch einfach halten und diesen Code verwenden
Wenn Sie eine Skriptdatei pass_it_on.sh mit diesem Code erstellen,
Du kannst rennen
und der gesamte inhalt von stdin wird einfach auf den bildschirm gespritzt.
Alternativ können Sie diesen Code verwenden, um eine Kopie von stdin in einer Datei zu speichern und diese dann auf den Bildschirm auszugeben.
und hier ist ein weiteres Beispiel, vielleicht besser lesbar, das hier erklärt wird:
http://mockingeye.com/blog/2013/01/22/reading-everything-stdin-in-a-bash-script/
Habe Spaß.
RaamEE
quelle
Der einfachste Weg und POSIX-konform ist:
das ist äquivalent zu
${1:--}
.Dann lies die Datei wie gewohnt:
quelle