Wie um zu überprüfen, ob stdin ist vom terminal oder einer pipe in ein shell-Skript?
Schreibe ich eine POSIX-shell-Skript, das möglicherweise oder möglicherweise nicht empfangen, die Eingabe von stdin als in foo.sh < test.txt
, nicht-interaktiv.
Wie kann ich prüfen, ob es irgendetwas gibt, was über stdin, um zu vermeiden, anhalten auf while read -r line...
?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn ich die Frage richtig, Sie können versuchen, die folgenden:
test -t n
ist wahr, wenn der file-Deskriptorn
ist geöffnet am terminal, sotest -t 0
prüft nur auf stdin undtest -t 1
prüft nur auf stdout.echo hello | interactive
undinteractive <(echo world)
produzieren verschiedene Ausgänge (im zsh)? (interactive
nur zurück 'ja' oder 'Nein'.) Ich sehe, dassinteractive <<<"goodnight"
undinteractive <moon.txt
beide funktionieren wie erwartet. (Meine intuition ist, dass<(command)
ist syntax-Zucker für etwas verwendet, die eine TTY -, aber ich weiß nicht, wie/warum.)<(command)
ist noch ein argument, es ist einfach nur ersetzt durch die Datei-Deskriptor für den stdout voncommand
.Antwort auf die Frage wörtlich (aber nicht das, was Sie eigentlich wollen):
read -t 0
Timeout null Sekunden.
-t 5
aber auf eine Tracht Prügel system selbst, die problematisch ist.read -t
ist nicht genormt, die in SUSv3. Es ist in der BSD-sh, bash, zsh. Es ist nicht in der ksh oder dash.Also kann man nicht einfach verwenden:#! /bin/sh und erwarten, dass diese.
Das grundlegende problem ist, dass selbst wenn es nichts, was auf stdin nun, das bedeutet nicht, es wird nicht bald sein. Ein Programm aufrufen, die normalerweise Blätter stdin an das terminal angeschlossen/was auch immer, so gibt es keine Möglichkeit zu sagen, was benötigt wird.
Also, um Ihre Frage zu beantworten wörtlich, Sie können es tun, aber in der Praxis sind Ihre Optionen:
[ -t 0 ]
read -t
oder gleichwertigread -t0
haben nicht deterministisch Verhalten. So wie Sie bereits erwähnt, vermeiden Sie es.-t
verwendet, in der Antwort.Können Sie ganz einfach implementieren, die ein ähnliches Verhalten wie die "cat" - Befehl, gelesen von einer Liste von zur Verfügung gestellten Dateien oder wenn Sie nicht, dann Lesen Sie von der Standardeingabe.
Obwohl Sie vielleicht nicht verwenden, diese Idee, ich denke, das Linux Journal Artikel wird für Sie interessant sein http://www.linuxjournal.com/content/determine-if-shell-input-coming-terminal-or-pipe
🙂
Wenn Sie nie wollen, um das Skript auszuführen interaktiv, stellen Sie den input-Datei als parameter, anstatt
stdin
. Einige Programme verwenden eine Flagge oder einen speziellen Dateinamen, um anzuzeigen, dass die Eingabe von der Standardeingabe statt aus einer Datei; diesem Fall können Sie Griff Befehlszeile Gerangel, wenn nötig.Wenn Sie wollen, dass Ihr script zu nehmen, die standard-Eingabe, warum willst du nicht lassen Sie es interaktiv sein (oder zumindest Verhalten sich wie andere POSIX-tools)?
-
statt einem Dateinamen.