Wie erkenne ich, ob mein Shell-Script durch eine Pipe läuft?
Wie erkenne ich in einem shell-Skript, wenn seine standard-Ausgabe ist, welche auf einem terminal oder ob es an einem anderen Prozess? (Case in point: ich möchte noch hinzufügen, escape-codes einfärben-Ausgang, aber nur, wenn Sie Sie interaktiv laufen lassen, aber nicht, wenn geleitet, ähnlich zu dem, was ls --color
tut.)
Kommentar zu dem Problem
Hier sind einige weitere interessante Testfälle! <a href="serverfault.com/questions/156470/... für ein Skript, das warten auf stdin</a>
@user940324 Der richtige link ist serverfault.com/q/156470/197218
InformationsquelleAutor der Frage | 2009-05-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
In eine Reine POSIX-shell,
gibt "terminal", weil die Ausgabe gesendet wird, um zu Ihrem terminal, während
gibt kein "terminal", weil der Ausgang des parenthetic ist an
cat
.Des-t-flag wird beschrieben in man-pages, die
... wo
fd
kann eine der üblichen Datei-Deskriptor Aufgaben:InformationsquelleAutor der Antwort dmckee
Gibt es keine narrensicher Weg, um zu bestimmen, wenn STDIN, STDOUT oder STDERR werden an/von deinem script, vor allem, weil Programme wie
ssh
.Dinge, die "normal" arbeiten
Beispielsweise die folgenden bash-Lösung funktioniert korrekt in einer interaktiven shell:
Aber Sie arbeiten nicht immer
Jedoch, wenn Sie diesen Befehl ausführen als nicht-TTY
ssh
Befehl, STD streams immer sieht, wie Sie sind verrohrt. Um dies zu demonstrieren, mit STDIN, weil es einfacher:Warum es wichtig ist
Dies ist eine ziemlich große Sache, weil es bedeutet, dass es keine Möglichkeit für ein bash-script zu sagen, ob ein nicht-tty
ssh
Befehl wird verrohrt oder nicht. Beachten Sie, dass dieses unglückliche Verhalten wurde eingeführt, wenn neuere Versionen vonssh
begann mit Rohren für nicht-TTY STDIO. Vorherige Versionen verwendet sockets, die unterscheiden KÖNNTE innerhalb der bash durch die Verwendung[[ -S ]]
., Wenn es darauf ankommt
Diese Einschränkung führt in der Regel zu Problemen, wenn Sie möchten schreiben Sie ein bash-Skript, das Verhalten ähnlich wie bei einer kompilierten utility, wie
cat
. Zum Beispielcat
können die folgenden flexibles Verhalten im Umgang mit verschiedenen input-Quellen gleichzeitig, und ist klug genug, um festzustellen, ob es erhalten wird geleitet Eingabe unabhängig davon, ob nicht-TTY-oder gezwungen-TTYssh
verwendet wird:Können Sie nur so etwas wie, dass, wenn Sie zuverlässig festzustellen, wenn die Rohre beteiligt sind oder nicht. Ansonsten, das ausführen eines Befehls, der liest von STDIN, wenn keine Eingabe vorhanden ist, die entweder aus Rohren oder-Umleitung Ergebnis in das Skript hängen und warten auf STDIN-Eingabe.
Andere Dinge, die nicht funktionieren
Versuchen, dieses problem zu lösen, habe ich mich an verschiedenen Techniken, die scheitern, um das problem zu lösen, einschließlich solcher, die Folgendes umfassen:
stat
auf /dev/stdin-Datei-Deskriptoren[[ "${ - }" =~ 'i' ]]
tty
undtty -s
ssh
status über[[ "$(ps -o comm= -p $PPID)" =~ 'sshd' ]]
Beachten Sie, dass wenn Sie verwenden ein Betriebssystem, das unterstützt die
/proc
virtuelles Dateisystem, könnten Sie Glück haben nach der symbolischen links für STDIO, um zu bestimmen, ob ein Rohr verwendet wird oder nicht. Allerdings/proc
ist kein cross-Plattform -, POSIX-kompatiblen Lösung.Bin ich äußerst interessant, dieses problem zu lösen, also bitte lassen Sie mich wissen, wenn Sie denken, der einer anderen Technik, die funktionieren könnte, vorzugsweise POSIX-basierte Lösungen, die auf Linux-und BSD.
InformationsquelleAutor der Antwort Dejay Clayton
Den Befehl
test
(builtin inbash
), hat eine option, um zu überprüfen, ob ein file-Deskriptor ist eine tty-Schnittstelle.Siehe "
man test
" oder "man bash
" und suchen Sie nach "-t
"InformationsquelleAutor der Antwort Beano
Du nicht erwähnt, welche shell Sie verwenden, aber in der Bash kann dies tun:
InformationsquelleAutor der Antwort Dan Moulding
Auf Solaris, der Vorschlag von Dejay Clayton funktioniert meistens. Das -p nicht wie gewünscht reagieren.
bash_redir_test.sh sieht aus wie:
Unter Linux, es funktioniert Super:
Unter Solaris:
InformationsquelleAutor der Antwort sbj3