-t FD
Vrai si FD est un descripteur de fichier associé à un terminal.
Donc, si vous exécutez bash en tant que shell interactif (terminal - voir ce fil pour l'explication de la terminologie), bash sera remplacé par zsh.
En savoir plus sur les fichiers .bash *:
Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que
shell non interactif avec l'option --login , il lit et exécute d'abord les commandes du fichier / etc / profile, si ce fichier existe. Après avoir lu ce fichier, il recherche ~ / .bash_profile, ~ / .bash_login et ~ / .profile, dans cet ordre, et lit et exécute les commandes à partir du premier qui existe et est lisible. L'option --noprofile peut être utilisée lorsque le shell est démarré pour inhiber ce comportement.
Lorsqu'un shell de connexion se ferme , bash lit et exécute les commandes des fichiers ~ / .bash_logout et /etc/bash.bash_logout, si les fichiers existent.
Lorsqu'un shell interactif qui n'est pas un shell de connexion est démarré, bash lit et exécute des commandes à partir de ~ / .bashrc , si ce fichier existe. Cela peut être inhibé en utilisant l'option --norc. L'option --rcfile file obligera bash à lire et exécuter des commandes à partir du fichier au lieu de ~ / .bashrc.
Commentaire de Stéphane Chazelas:
Notez qu'un shell peut être interactif sans que stdout soit un terminal, et un shell peut être non interactif avec un terminal sur stdout (comme à chaque fois que vous exécutez un script dans un terminal sans rediriger / canaliser sa sortie), et bashpeut lire .bashrcmême lorsqu'il n'est pas interactif (comme dans ssh host cmdoù se bashtrouve le shell de connexion de l'utilisateur sur l'hôte, ou bash --login -c 'some code'). case $- in *i*)...est la bonne façon de tester si un shell est interactif.
Notez qu'un shell peut être interactif sans que stdout soit un terminal, et un shell peut être non interactif avec un terminal sur stdout (comme à chaque fois que vous exécutez un script dans un terminal sans rediriger / rediriger sa sortie), et bashpeut lire .bashrcmême lorsqu'il n'est pas interactif (comme ssh host cmdoù se bashtrouve le shell de connexion de l'utilisateur sur l'hôte, ou bash --login -c 'some code'où les .bash_profilesources le .bashrc). case $- in *i*)...est la bonne façon de tester si un shell est interactif.
Stéphane Chazelas
@ StéphaneChazelas bon point. Je contiendrai votre commentaire en réponse
mrc02_kr
Il existe différentes définitions de «interactif». Si le shell pense qu'il est interactif, alors iil sera défini (et dans les shells modernes qui peuvent être testés avec ifau lieu d'avoir à utiliser case). Mais il existe de nombreux cas d'utilisation où l'on ne se soucie que si stdout (ou stdin, ou stderr ...) est attaché à un terminal.
Mark Reed
9
La commande test[ -t 1 ] vérifie si la sortie de bash se trouve sur un terminal. L'intention de cette ligne est clairement d'exécuter zsh lors de l'ouverture d'un terminal, sans perturber les autres utilisations de bash. Mais c'est très mal fait.
Le fichier .bashrcest lu dans trois circonstances:
Lorsque bash est exécuté comme un shell interactif, c'est-à-dire pour exécuter des commandes tapées par l'utilisateur plutôt que pour exécuter des commandes batch.
Lorsque bash est un shell non interactif qui est exécuté par un démon RSH ou SSH (généralement parce que vous exécutez ssh host.example.com somecommandet bash est votre shell de connexion activé host.example.com).
[ -t 1 ]est un mauvais moyen de détecter les shells interactifs. Il est possible, mais rare, d'exécuter bash de manière interactive avec une sortie standard ne allant pas vers un terminal. Il est plus courant d'avoir une sortie standard vers un terminal dans un shell non interactif; un shell non interactif ne fonctionne pas, .bashrcmais malheureusement les shell bash invoqués par SSH le font. Il y a une bien meilleure façon: bash (et tout autre shell de style sh) fournit une méthode intégrée et fiable pour le faire.
case $-in*i*) echo this shell is interactive;;*) echo this shell is not interactive;;esac
Donc, "lancez zsh s'il s'agit d'un shell interactif" devrait être écrit
case $-in*i*) exec zsh;;esac
Mais même ce n'est pas une bonne idée: cela empêche d'ouvrir un shell bash, ce qui est utile même si vous utilisez zsh. Oubliez cet article de blog et configurez simplement votre raccourci qui ouvre un terminal pour exécuter zsh au lieu de bash. N'arrangez pas les choses pour que «chaque fois que vous ouvrez l'application Bash sur Windows, elle démarre maintenant avec le shell Zsh»: lorsque vous voulez zsh, ouvrez l'application Zsh.
Pour rsh/ sshet pour le shell interactif, c'est si ce n'est pas un shell de connexion. Pour les shells de connexion ( sshdne démarre pas un shell de connexion non interactif, mais vous pouvez le faire avec ssh host exec bash -l), .bash_profileest lu à la place. Notez également que pour rsh/ ssh, vous devez également $SHLVLêtre non défini ou 0.
le descripteur de fichier FD est ouvert sur un terminal
Votre exemple s'exécute (remplace le processus en cours, dans ce cas bash) avec zshon si stdout est ouvert sur un terminal (pas un fichier / pipe / etc).
bash
peut lire.bashrc
même lorsqu'il n'est pas interactif (commessh host cmd
où sebash
trouve le shell de connexion de l'utilisateur sur l'hôte, oubash --login -c 'some code'
où les.bash_profile
sources le.bashrc
).case $- in *i*)...
est la bonne façon de tester si un shell est interactif.i
il sera défini (et dans les shells modernes qui peuvent être testés avecif
au lieu d'avoir à utilisercase
). Mais il existe de nombreux cas d'utilisation où l'on ne se soucie que si stdout (ou stdin, ou stderr ...) est attaché à un terminal.La commande test
[ -t 1 ]
vérifie si la sortie de bash se trouve sur un terminal. L'intention de cette ligne est clairement d'exécuter zsh lors de l'ouverture d'un terminal, sans perturber les autres utilisations de bash. Mais c'est très mal fait.Le fichier
.bashrc
est lu dans trois circonstances:ssh host.example.com somecommand
et bash est votre shell de connexion activéhost.example.com
)..bash_profile
( le choix de bash des fichiers de démarrage est un peu bizarre ).[ -t 1 ]
est un mauvais moyen de détecter les shells interactifs. Il est possible, mais rare, d'exécuter bash de manière interactive avec une sortie standard ne allant pas vers un terminal. Il est plus courant d'avoir une sortie standard vers un terminal dans un shell non interactif; un shell non interactif ne fonctionne pas,.bashrc
mais malheureusement les shell bash invoqués par SSH le font. Il y a une bien meilleure façon: bash (et tout autre shell de style sh) fournit une méthode intégrée et fiable pour le faire.Donc, "lancez zsh s'il s'agit d'un shell interactif" devrait être écrit
Mais même ce n'est pas une bonne idée: cela empêche d'ouvrir un shell bash, ce qui est utile même si vous utilisez zsh. Oubliez cet article de blog et configurez simplement votre raccourci qui ouvre un terminal pour exécuter zsh au lieu de bash. N'arrangez pas les choses pour que «chaque fois que vous ouvrez l'application Bash sur Windows, elle démarre maintenant avec le shell Zsh»: lorsque vous voulez zsh, ouvrez l'application Zsh.
la source
rsh
/ssh
et pour le shell interactif, c'est si ce n'est pas un shell de connexion. Pour les shells de connexion (sshd
ne démarre pas un shell de connexion non interactif, mais vous pouvez le faire avecssh host exec bash -l
),.bash_profile
est lu à la place. Notez également que pourrsh
/ssh
, vous devez également$SHLVL
être non défini ou 0.test homme 1 :
Votre exemple s'exécute (remplace le processus en cours, dans ce cas
bash
) aveczsh
on si stdout est ouvert sur un terminal (pas un fichier / pipe / etc).la source