Cosa controlla [-t 1]?


Risposte:


14

[]è una scorciatoia di testcomando.

Secondo man test:

-t FD
Vero se FD è un descrittore di file associato a un terminale.

Quindi se si esegue bash come shell interattiva (terminale - vedere questo thread per la spiegazione della terminologia), bash verrà sostituito da zsh.

Ulteriori informazioni sui file .bash *:

Quando bash viene invocato come shell di login interattiva o come shell non interattiva con l'opzione --login , legge prima ed esegue i comandi dal file / etc / profile, se quel file esiste. Dopo aver letto quel file, cerca ~ / .bash_profile, ~ / .bash_login e ~ / .profile, in quell'ordine, e legge ed esegue i comandi dal primo che esiste ed è leggibile. L'opzione --noprofile può essere usata all'avvio della shell per inibire questo comportamento.

Quando una shell di login esce , bash legge ed esegue i comandi dai file ~ / .bash_logout e /etc/bash.bash_logout, se i file esistono.

Quando viene avviata una shell interattiva che non è una shell di accesso , bash legge ed esegue i comandi da ~ / .bashrc , se quel file esiste. Questo può essere inibito usando l'opzione --norc. L'opzione --rcfile forzerà bash a leggere ed eseguire comandi dal file invece di ~ / .bashrc.

Commento di Stéphane Chazelas:
Notare che una shell può essere interattiva senza che stdout sia un terminale e che una shell possa non essere interattiva con un terminale su stdout (come ogni volta che si esegue uno script all'interno di un terminale senza reindirizzare / reindirizzare l'output), e bashpuò leggere .bashrcanche quando non interattivo (come in ssh host cmddove si bashtrova la shell di accesso dell'utente sull'host o bash --login -c 'some code'). case $- in *i*)...è il modo corretto di verificare se una shell è interattiva.


4
Si noti che una shell può essere interattiva senza che stdout sia un terminale e una shell non può essere interattiva con un terminale su stdout (come ogni volta che si esegue uno script all'interno di un terminale senza reindirizzare / reindirizzare l'output) e bashleggere .bashrcanche quando non interattivo (come ssh host cmddove si bashtrova la shell di accesso dell'utente sull'host o bash --login -c 'some code'dove si trovano le .bash_profilefonti .bashrc). case $- in *i*)...è il modo corretto per verificare se una shell è interattiva.
Stéphane Chazelas,

@ StéphaneChazelas buon punto.
Conterrò il

Esistono diverse definizioni di "interattivo". Se la shell pensa che sia interattiva, iverrà impostata (e nelle shell moderne che possono essere testate ifinvece di doverle usare case). Ma ci sono molti casi d'uso in cui uno si preoccupa solo se stdout (o stdin, o stderr ...) è collegato a un terminale.
Mark Reed,

9

Il comando test [ -t 1 ] verifica se l'output di bash è su un terminale. L'intento di questa linea è chiaramente quello di eseguire zsh quando si apre un terminale, senza interrompere altri usi di bash. Ma è fatto molto male.

Il file .bashrcviene letto in tre circostanze:

  • Quando bash viene eseguito come shell interattiva, ovvero per eseguire comandi digitati dall'utente anziché eseguire comandi batch.
  • Quando bash è una shell non interattiva che viene eseguita da un demone RSH o SSH (in genere perché si esegue ssh host.example.com somecommande bash è la shell di accesso attiva host.example.com).
  • Quando viene invocato esplicitamente, ad esempio in un utente .bash_profile( la scelta dei file di avvio di bash è un po 'strana ).

[ -t 1 ]è un modo scadente per rilevare shell interattive. È possibile, ma raro, eseguire bash in modo interattivo con l'output standard non andando a un terminale. È più comune avere l'output standard su un terminale in una shell non interattiva; una shell non interattiva non ha attività in esecuzione .bashrcma sfortunatamente le shell bash invocate da SSH lo fanno. C'è un modo molto migliore: bash (e qualsiasi altra shell sh-style) fornisce un metodo integrato e affidabile per farlo.

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

Quindi dovrebbe essere scritto "avvia zsh se questa è una shell interattiva"

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

Ma anche questa non è una buona idea: impedisce l'apertura di una shell bash, che è utile anche se usi zsh. Dimentica questo post sul blog e invece configura semplicemente il tuo collegamento che apre un terminale per eseguire zsh invece di bash. Non organizzare le cose in modo che "ogni volta che apri l'applicazione Bash su Windows, ora si avvierà con la shell Zsh": quando vuoi zsh, apri l'applicazione Zsh.


Per rsh/ sshe per la shell interattiva, è se non è una shell di accesso. Per le shell di accesso ( sshdnon si avvia una shell di accesso non interattiva, ma è possibile farlo con ssh host exec bash -l), .bash_profileviene invece letto. Si noti inoltre che per rsh/ ssh, è necessario anche $SHLVLessere non impostati o 0.
Stéphane Chazelas

5

man 1 test :

-t FD

il descrittore di file FD è aperto su un terminale

Il tuo esempio viene eseguito (sostituisce il processo in esecuzione, in questo caso bash) con zshon se stdout è aperto su un terminale (non un file / pipe / etc).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.