-t FD
Prawda, jeśli FD jest deskryptorem pliku powiązanym z terminalem.
Jeśli więc uruchomisz bash jako interaktywną powłokę (terminal - objaśnienie terminologii znajdziesz w tym wątku), bash zostanie zastąpiony przez zsh.
Więcej informacji o plikach .bash *:
Kiedy bash jest wywoływany jako interaktywna powłoka logowania lub jako
nieinteraktywna powłoka z opcją --login , najpierw czyta i wykonuje polecenia z pliku / etc / profile, jeśli plik ten istnieje. Po odczytaniu tego pliku szuka ~ / .bash_profile, ~ / .bash_login i ~ / .profile, w tej kolejności, i odczytuje i wykonuje polecenia z pierwszego, który istnieje i jest możliwy do odczytu. Opcji --noprofile można użyć, gdy powłoka zostanie uruchomiona w celu zahamowania tego zachowania.
Po wyjściu z powłoki logowania bash czyta i wykonuje polecenia z plików ~ / .bash_logout i /etc/bash.bash_logout, jeśli pliki istnieją.
Po uruchomieniu interaktywnej powłoki, która nie jest powłoką logowania , bash czyta i wykonuje polecenia z ~ / .bashrc , jeśli plik istnieje. Można temu zapobiec, używając opcji --norc. Opcja --rcfile pliku zmusi bash do odczytu i wykonywania poleceń z pliku zamiast ~ / .bashrc.
Komentarz Stéphane Chazelas:
Zauważ, że powłoka może być interaktywna bez stdout jako terminala, a powłoka może być nieinteraktywna z terminalem na stdout (jak za każdym razem, gdy uruchamiasz skrypt w terminalu bez przekierowywania / przesyłania potokowego jego danych wyjściowych) i bashmoże czytać, .bashrcnawet gdy nie jest interaktywny (np. ssh host cmdgdzie bashznajduje się powłoka logowania użytkownika na hoście lub bash --login -c 'some code'). case $- in *i*)...jest poprawnym sposobem sprawdzenia, czy powłoka jest interaktywna.
Zauważ, że powłoka może być interaktywna bez stdout jako terminala, a powłoka może być nieinteraktywna z terminalem na stdout (jak za każdym razem, gdy uruchamiasz skrypt w terminalu bez przekierowywania / przesyłania potokowego danych wyjściowych), i bashmoże czytać, .bashrcnawet jeśli nie jest interaktywne (np. ssh host cmdgdzie bashznajduje się powłoka logowania użytkownika na hoście lub bash --login -c 'some code'gdzie .bash_profileźródła .bashrc). case $- in *i*)...jest poprawnym sposobem sprawdzenia, czy powłoka jest interaktywna.
Stéphane Chazelas
@ StéphaneChazelas dobry punkt. W odpowiedzi
zawrę
Istnieje wiele różnych definicji „interaktywnych”. Jeśli powłoka uważa, że jest interaktywna, izostanie ustawiona (i we współczesnych powłokach, które można przetestować ifzamiast używać case). Ale istnieje wiele przypadków użycia, w których obchodzi się tylko, jeśli stdout (lub stdin lub stderr ...) jest podłączony do terminala.
Mark Reed
9
Polecenie testowe[ -t 1 ] sprawdza, czy wyjście bash jest w terminalu. Celem tej linii jest oczywiście uruchomienie zsh podczas otwierania terminala, bez zakłócania innych zastosowań bash. Ale zrobiono to bardzo źle.
Plik .bashrcjest odczytywany w trzech okolicznościach:
Gdy bash jest wykonywany jako interaktywna powłoka, tj. Do uruchamiania poleceń wpisanych przez użytkownika, a nie do wykonywania poleceń wsadowych.
Gdy bash jest nieinteraktywną powłoką, która jest uruchamiana przez demona RSH lub SSH (zazwyczaj dlatego, że działasz ssh host.example.com somecommandi bash jest twoją powłoką logowania host.example.com).
[ -t 1 ]jest złym sposobem wykrywania interaktywnych powłok. Możliwe jest, ale rzadko, uruchamianie basha interaktywnie ze standardowym wyjściem, który nie przechodzi do terminala. Częściej zdarza się, że standardowe wyjście trafia do terminala w nieinteraktywnej powłoce; nieinteraktywna powłoka nie działa, .bashrcale niestety powłoki bash wywoływane przez SSH do. Jest o wiele lepszy sposób: bash (i każda inna powłoka w stylu sh) zapewnia wbudowaną, niezawodną metodę tego.
case $-in*i*) echo this shell is interactive;;*) echo this shell is not interactive;;esac
Dlatego należy napisać „uruchom zsh, jeśli jest to powłoka interaktywna”
case $-in*i*) exec zsh;;esac
Ale nawet to nie jest dobry pomysł: zapobiega otwieraniu powłoki bash, co jest przydatne, nawet jeśli używasz zsh. Zapomnij o tym wpisie na blogu i zamiast tego skonfiguruj skrót otwierający terminal do uruchamiania zsh zamiast bash. Nie układaj rzeczy w taki sposób, aby „za każdym razem, gdy otworzysz aplikację Bash w systemie Windows, uruchomi się ona z powłoką Zsh”: kiedy chcesz zsh, otwórz aplikację Zsh.
Dla rsh/ sshi na interaktywnej powłoki, to czy to nie powłoka logowania. W przypadku powłok logowania ( sshdnie uruchamiałoby się nieinteraktywnej powłoki logowania, ale można to zrobić za pomocą ssh host exec bash -l), .bash_profileczytane jest zamiast. Zauważ też, że dla rsh/ ssh, musisz także $SHLVLbyć rozbrojony lub 0.
Twój przykład jest wykonywany (w tym przypadku zastępuje działający proces bash) przez zshon, jeśli stdout jest otwarty na terminalu (nie w pliku / potoku / itp.).
bash
może czytać,.bashrc
nawet jeśli nie jest interaktywne (np.ssh host cmd
gdziebash
znajduje się powłoka logowania użytkownika na hoście lubbash --login -c 'some code'
gdzie.bash_profile
źródła.bashrc
).case $- in *i*)...
jest poprawnym sposobem sprawdzenia, czy powłoka jest interaktywna.i
zostanie ustawiona (i we współczesnych powłokach, które można przetestowaćif
zamiast używaćcase
). Ale istnieje wiele przypadków użycia, w których obchodzi się tylko, jeśli stdout (lub stdin lub stderr ...) jest podłączony do terminala.Polecenie testowe
[ -t 1 ]
sprawdza, czy wyjście bash jest w terminalu. Celem tej linii jest oczywiście uruchomienie zsh podczas otwierania terminala, bez zakłócania innych zastosowań bash. Ale zrobiono to bardzo źle.Plik
.bashrc
jest odczytywany w trzech okolicznościach:ssh host.example.com somecommand
i bash jest twoją powłoką logowaniahost.example.com
)..bash_profile
( wybór plików startowych przez bash jest nieco dziwny ).[ -t 1 ]
jest złym sposobem wykrywania interaktywnych powłok. Możliwe jest, ale rzadko, uruchamianie basha interaktywnie ze standardowym wyjściem, który nie przechodzi do terminala. Częściej zdarza się, że standardowe wyjście trafia do terminala w nieinteraktywnej powłoce; nieinteraktywna powłoka nie działa,.bashrc
ale niestety powłoki bash wywoływane przez SSH do. Jest o wiele lepszy sposób: bash (i każda inna powłoka w stylu sh) zapewnia wbudowaną, niezawodną metodę tego.Dlatego należy napisać „uruchom zsh, jeśli jest to powłoka interaktywna”
Ale nawet to nie jest dobry pomysł: zapobiega otwieraniu powłoki bash, co jest przydatne, nawet jeśli używasz zsh. Zapomnij o tym wpisie na blogu i zamiast tego skonfiguruj skrót otwierający terminal do uruchamiania zsh zamiast bash. Nie układaj rzeczy w taki sposób, aby „za każdym razem, gdy otworzysz aplikację Bash w systemie Windows, uruchomi się ona z powłoką Zsh”: kiedy chcesz zsh, otwórz aplikację Zsh.
źródło
rsh
/ssh
i na interaktywnej powłoki, to czy to nie powłoka logowania. W przypadku powłok logowania (sshd
nie uruchamiałoby się nieinteraktywnej powłoki logowania, ale można to zrobić za pomocąssh host exec bash -l
),.bash_profile
czytane jest zamiast. Zauważ też, że dlarsh
/ssh
, musisz także$SHLVL
być rozbrojony lub 0.test człowieka 1 :
Twój przykład jest wykonywany (w tym przypadku zastępuje działający proces
bash
) przezzsh
on, jeśli stdout jest otwarty na terminalu (nie w pliku / potoku / itp.).źródło