O que [-t 1] verifica?

Respostas:

14

[]é um atalho de testcomando.

De acordo com man test:

-t FD
True se FD for um descritor de arquivo associado a um terminal.

Portanto, se você estiver executando o bash como shell interativo (terminal - veja esta discussão para obter uma explicação da terminologia), o bash será substituído pelo zsh.

Mais sobre arquivos .bash *:

Quando o bash é chamado como um shell de logon interativo ou como um shell não interativo com a opção --login , ele primeiro lê e executa comandos do arquivo / etc / profile, se esse arquivo existir. Depois de ler esse arquivo, ele procura ~ / .bash_profile, ~ / .bash_login e ~ / .profile, nessa ordem, e lê e executa comandos do primeiro que existe e é legível. A opção --noprofile pode ser usada quando o shell é iniciado para inibir esse comportamento.

Quando um shell de login sai , o bash lê e executa comandos dos arquivos ~ / .bash_logout e /etc/bash.bash_logout, se os arquivos existirem.

Quando um shell interativo que não é um shell de login é iniciado, o bash lê e executa comandos de ~ / .bashrc , se esse arquivo existir. Isso pode ser inibido usando a opção --norc. A opção --rcfile file forçará o bash a ler e executar comandos do arquivo em vez de ~ / .bashrc.

Comentário de Stéphane Chazelas:
Observe que um shell pode ser interativo sem o stdout ser um terminal, e um shell pode não ser interativo com um terminal no stdout (como sempre que você executa um script em um terminal sem redirecionar / canalizar sua saída) e bashpode leia .bashrcmesmo quando não for interativo (como em ssh host cmdonde bashestá o shell de login do usuário no host ou bash --login -c 'some code'). case $- in *i*)...é a maneira correta de testar se um shell é interativo.

mrc02_kr
fonte
4
Observe que um shell pode ser interativo sem que o stdout seja um terminal, e um shell pode não ser interativo com um terminal no stdout (como sempre que você executa um script em um terminal sem redirecionar / canalizar sua saída) e bashpode ler .bashrcmesmo quando não está. interativo (como em ssh host cmdonde bashestá o shell de login do usuário no host ou bash --login -c 'some code'onde as .bash_profilefontes estão .bashrc). case $- in *i*)...é a maneira correta de testar se um shell é interativo.
Stéphane Chazelas
@ StéphaneChazelas bom ponto. I irá conter seu comentário em resposta
mrc02_kr
Existem várias definições diferentes de "interativo". Se o shell considerar interativo, iserá definido (e em shells modernos que podem ser testados em ifvez de serem usados case). Mas há muitos casos de uso em que apenas se importa se stdout (ou stdin ou stderr ...) está conectado a um terminal.
Mark Reed
9

O comando test [ -t 1 ] verifica se a saída do bash está em um terminal. A intenção desta linha é claramente executar o zsh ao abrir um terminal, sem interromper outros usos do bash. Mas é feito muito mal.

O arquivo .bashrcé lido em três circunstâncias:

  • Quando o bash é executado como um shell interativo, ou seja, para executar comandos digitados pelo usuário, em vez de executar comandos em lote.
  • Quando bash é um shell não interativo que é executado por um daemon RSH ou SSH (normalmente porque você executa ssh host.example.com somecommande o bash é seu shell de logon host.example.com).
  • Quando é chamado explicitamente, por exemplo, no usuário .bash_profile( a escolha dos arquivos de inicialização do bash é um pouco estranha ).

[ -t 1 ]é uma maneira ruim de detectar shells interativos. É possível, mas raro, executar o bash interativamente com a saída padrão que não vai para um terminal. É mais comum ter saída padrão indo para um terminal em um shell não interativo; um shell não interativo não tem negócios em execução, .bashrcmas infelizmente os shells bash invocados pelo SSH fazem. Existe uma maneira muito melhor: o bash (e qualquer outro shell do estilo sh) fornece um método confiável e incorporado para fazer isso.

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

Portanto, “lance o zsh se for um shell interativo” deve ser escrito

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

Mas mesmo isso não é uma boa ideia: impede a abertura de um shell bash, o que é útil mesmo se você usar o zsh. Esqueça esta postagem no blog e simplesmente configure seu atalho que abre um terminal para executar o zsh em vez do bash. Não organize as coisas para que “sempre que você abrir o aplicativo Bash no Windows, ele iniciará com o shell Zsh”: quando você quiser o zsh, abra o aplicativo Zsh.

Gilles 'SO- parar de ser mau'
fonte
Para rsh/ sshe para shell interativo, é se não for um shell de login. Para shells de logon ( sshdnão iniciaria um shell de logon não interativo, mas você poderia fazê-lo ssh host exec bash -l), .bash_profileé lido em vez disso. Observe também que, para rsh/ ssh, você também precisa $SHLVLestar desabilitado ou 0. #
Stéphane Chazelas 4/17/17
5

teste homem 1 :

-t FD

O descritor de arquivo FD é aberto em um terminal

Seu exemplo é executado (substitui o processo em execução, neste caso bash) por zshon se stdout estiver aberto em um terminal (não em um arquivo / pipe / etc).

sebasth
fonte