Was prüft [-t 1]?

Antworten:

14

[]ist eine Abkürzung des testBefehls.

Nach man test:

-t FD
True, wenn FD ein Dateideskriptor ist, der einem Terminal zugeordnet ist.

Wenn Sie also bash als interaktive Shell ausführen (Terminal - Terminologieerklärungen finden Sie in diesem Thread), wird bash durch zsh ersetzt.

Weitere Informationen zu .bash * -Dateien:

Wenn bash als interaktive Anmeldeshell oder als nicht interaktive Shell mit der Option --login aufgerufen wird , werden zuerst Befehle aus der Datei / etc / profile gelesen und ausgeführt, sofern diese Datei vorhanden ist. Nach dem Lesen dieser Datei sucht sie in dieser Reihenfolge nach ~ / .bash_profile, ~ / .bash_login und ~ / .profile und liest und führt Befehle von der ersten Datei aus, die vorhanden und lesbar ist. Die Option --noprofile kann verwendet werden, wenn die Shell gestartet wird, um dieses Verhalten zu unterbinden.

Wenn eine Login-Shell beendet wird , liest bash Befehle aus den Dateien ~ / .bash_logout und /etc/bash.bash_logout und führt sie aus, sofern diese Dateien vorhanden sind.

Wenn eine interaktive Shell gestartet wird, die keine Anmeldeshell ist, liest bash Befehle von ~ / .bashrc und führt sie aus , sofern diese Datei vorhanden ist. Dies kann mit der Option --norc verhindert werden. Die Option --rcfile file erzwingt, dass Bash anstelle von ~ / .bashrc Befehle aus der Datei liest und ausführt.

Stéphane Chazelas Kommentar:
Beachten Sie, dass eine Hülle ohne stdout interaktiv sein kann , ein Terminal zu sein, und eine Schale mit einem Terminal auf stdout nicht interaktiv sein (wie , wann immer Sie ein Skript in einem Terminal ohne Umlenken / kochend seinen Ausgang) und bashDose lesen , .bashrcauch wenn nicht interaktiv (wie in ssh host cmddem bashist die Login - Shell des Benutzers auf dem Host oder bash --login -c 'some code'). case $- in *i*)...ist der richtige Weg, um zu testen, ob eine Shell interaktiv ist.

mrc02_kr
quelle
4
Beachten Sie, dass eine Shell interaktiv sein kann, ohne dass stdout ein Terminal ist, und eine Shell mit einem Terminal auf stdout nicht interaktiv sein kann (wie jedes Mal, wenn Sie ein Skript in einem Terminal ausführen, ohne dessen Ausgabe umzuleiten / weiterzuleiten) und bashauch dann lesen kann, .bashrcwenn dies nicht der Fall ist interaktiv (wie in ssh host cmdwo bashist die Login-Shell des Benutzers auf dem Host oder bash --login -c 'some code'wo die .bash_profileQuellen die .bashrc). case $- in *i*)...ist der richtige Weg, um zu testen, ob eine Shell interaktiv ist.
Stéphane Chazelas
@ StéphaneChazelas guter Punkt. Ich werde Ihren Kommentar in Antwort enthalten
mrc02_kr
Es gibt verschiedene Definitionen von "interaktiv". Wenn die Shell denkt , dass sie interaktiv ist, iwird sie gesetzt (und in modernen Shells, mit denen getestet werden kann, ifanstatt sie verwenden zu müssen case). Aber es gibt viele Anwendungsfälle, bei denen man sich nur darum kümmert, ob stdout (oder stdin oder stderr ...) an ein Terminal angeschlossen ist.
Mark Reed
9

Der Testbefehl [ -t 1 ] prüft, ob die Ausgabe der Bash auf einem Terminal ist. Die Absicht dieser Zeile ist eindeutig, zsh auszuführen, wenn ein Terminal geöffnet wird, ohne andere Verwendungen von bash zu stören. Aber es ist sehr schlecht gemacht.

Die Datei .bashrcwird unter drei Umständen gelesen:

  • Wenn bash als interaktive Shell ausgeführt wird, dh um vom Benutzer eingegebene Befehle auszuführen, anstatt Stapelbefehle auszuführen.
  • Wenn bash eine nicht interaktive Shell ist, die von einem RSH- oder SSH-Daemon ausgeführt wird (normalerweise, weil Sie ssh host.example.com somecommandbash ausführen und Ihre Anmeldeshell aktiviert ist host.example.com).
  • Wenn es explizit aufgerufen wird, z. B. in einem Benutzer .bash_profile( die Auswahl der Startdateien durch Bash ist etwas seltsam ).

[ -t 1 ]ist ein schlechter Weg, um interaktive Shells zu erkennen. Es ist möglich, aber selten, bash interaktiv mit Standardausgaben auszuführen, die nicht an ein Terminal gesendet werden. Normalerweise wird die Standardausgabe in einer nicht interaktiven Shell an ein Terminal gesendet. Bei einer nicht interaktiven Shell läuft kein Geschäft, .bashrcaber von SSH aufgerufene Bash-Shells tun dies leider. Es gibt einen viel besseren Weg: bash (und jede andere Shell im Sh-Stil) bietet eine eingebaute, zuverlässige Methode, um dies zu tun.

case $- in
  *i*) echo this shell is interactive;;
  *) echo this shell is not interactive;;
esac

Also sollte "start zsh wenn dies eine interaktive Shell ist" geschrieben werden

case $- in
  *i*) exec zsh;;
esac

Aber auch das ist keine gute Idee: Es verhindert das Öffnen einer Bash-Shell, was selbst bei Verwendung von zsh nützlich ist. Vergessen Sie diesen Blog-Beitrag und konfigurieren Sie stattdessen einfach Ihre Verknüpfung, die ein Terminal öffnet, um zsh anstelle von bash auszuführen. Ordnen Sie die Dinge nicht so an, dass "wenn Sie die Bash-Anwendung unter Windows öffnen, wird sie jetzt mit der Zsh-Shell gestartet": Wenn Sie Zsh möchten, öffnen Sie die Zsh-Anwendung.

Gilles 'SO - hör auf böse zu sein'
quelle
Für rsh/ sshund für die interaktive Shell ist es, wenn es keine Anmeldeshell ist. Für Login-Shells ( sshdwürde keine nicht-interaktive Login-Shell starten, aber Sie könnten es mit tun ssh host exec bash -l), .bash_profilewird stattdessen gelesen. Beachten Sie auch , dass Sie für rsh/ sshauch $SHLVLnicht gesetzt oder 0 sein müssen.
Stéphane Chazelas
5

Mann 1 Test :

-t FD

Dateideskriptor FD wird auf einem Terminal geöffnet

Ihr Beispiel wird ausgeführt (ersetzt in diesem Fall den laufenden Prozess bash) mit zshon, wenn stdout auf einem Terminal geöffnet ist (keine Datei / Pipe / etc).

sebasth
quelle