¿Qué verifica [-t 1]?

Respuestas:

14

[]es atajo de testcomando.

De acuerdo a man test:

-t FD
Verdadero si FD es un descriptor de archivo asociado con un terminal.

Entonces, si ejecuta bash como shell interactivo (terminal, consulte este hilo para obtener una explicación de la terminología), bash será reemplazado por zsh.

Más información sobre los archivos .bash *:

Cuando se invoca bash como un shell de inicio de sesión interactivo , o como un shell no interactivo con la opción --login , primero lee y ejecuta comandos del archivo / etc / profile, si ese archivo existe. Después de leer ese archivo, busca ~ / .bash_profile, ~ / .bash_login y ~ / .profile, en ese orden, y lee y ejecuta comandos del primero que existe y es legible. La opción --noprofile se puede usar cuando se inicia el shell para inhibir este comportamiento.

Cuando sale un shell de inicio de sesión , bash lee y ejecuta comandos de los archivos ~ / .bash_logout y /etc/bash.bash_logout, si los archivos existen.

Cuando se inicia un shell interactivo que no es un shell de inicio de sesión , bash lee y ejecuta comandos desde ~ / .bashrc , si ese archivo existe. Esto puede inhibirse utilizando la opción --norc. La opción de archivo --rcfile obligará a bash a leer y ejecutar comandos desde el archivo en lugar de ~ / .bashrc.

Comentario de Stéphane Chazelas:
Tenga en cuenta que un shell puede ser interactivo sin que stdout sea un terminal, y un shell puede no ser interactivo con un terminal en stdout (como cada vez que ejecuta un script dentro de un terminal sin redirigir / canalizar su salida), y bashpuede leer .bashrcincluso cuando no es interactivo (como en ssh host cmddónde bashestá el shell de inicio de sesión del usuario en el host, o bash --login -c 'some code'). case $- in *i*)...es la forma correcta de probar si un shell es interactivo.

mrc02_kr
fuente
44
Tenga en cuenta que un shell puede ser interactivo sin que stdout sea un terminal, y un shell puede no ser interactivo con un terminal en stdout (como cada vez que ejecuta un script dentro de un terminal sin redirigir / canalizar su salida), y bashpuede leer .bashrcincluso cuando no interactivo (como en ssh host cmddónde bashestá el shell de inicio de sesión del usuario en el host o bash --login -c 'some code'dónde están las .bash_profilefuentes .bashrc). case $- in *i*)...es la forma correcta de probar si un shell es interactivo.
Stéphane Chazelas
@ StéphaneChazelas buen punto. Contestaré su comentario en respuesta
mrc02_kr
Hay varias definiciones diferentes de "interactivo". Si el shell cree que es interactivo, ise establecerá (y en los shells modernos que se pueden probar en iflugar de tener que usar case). Pero hay muchos casos de uso en los que a uno solo le importa si stdout (o stdin, o stderr ...) está conectado a un terminal.
Mark Reed
9

El comando de prueba [ -t 1 ] verifica si la salida de bash está en una terminal. La intención de esta línea es claramente ejecutar zsh al abrir una terminal, sin interrumpir otros usos de bash. Pero está hecho muy mal.

El archivo .bashrcse lee en tres circunstancias:

  • Cuando bash se ejecuta como un shell interactivo, es decir, para ejecutar comandos escritos por el usuario en lugar de ejecutar comandos por lotes.
  • Cuando bash es un shell no interactivo que es ejecutado por un demonio RSH o SSH (generalmente porque ejecuta ssh host.example.com somecommandy bash es su shell de inicio de sesión host.example.com).
  • Cuando se invoca explícitamente, por ejemplo, en un usuario .bash_profile( la elección de bash de los archivos de inicio es un poco extraña ).

[ -t 1 ]es una forma pobre de detectar shells interactivos. Es posible, pero raro, ejecutar bash interactivamente con salida estándar que no va a una terminal. Es más común que la salida estándar vaya a un terminal en un shell no interactivo; un shell no interactivo no tiene actividad ejecutándose, .bashrcpero desafortunadamente los shells bash invocados por SSH sí. Hay una manera mucho mejor: bash (y cualquier otro shell de estilo sh) proporciona un método integrado y confiable para hacerlo.

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

Por lo tanto, se debe escribir "lanzar zsh si se trata de un shell interactivo"

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

Pero incluso eso no es una buena idea: evita abrir un shell bash, lo cual es útil incluso si usa zsh. Olvídate de esta publicación de blog y simplemente configura tu acceso directo que abre un terminal para ejecutar zsh en lugar de bash. No organice las cosas para que "cada vez que abra la aplicación Bash en Windows, ahora se inicie con el shell Zsh": cuando desee zsh, abra la aplicación Zsh.

Gilles 'SO- deja de ser malvado'
fuente
Por rsh/ sshy para la consola interactiva, es si es no un intérprete de ingreso. Para shells de inicio de sesión ( sshdno iniciaría un shell de inicio de sesión no interactivo, pero podría hacerlo con ssh host exec bash -l), .bash_profilese lee en su lugar. También tenga en cuenta que para rsh/ ssh, también debe $SHLVLestar desarmado o 0.
Stéphane Chazelas
5

prueba hombre 1 :

-t FD

el descriptor de archivo FD se abre en un terminal

Su ejemplo se ejecuta (reemplaza el proceso en ejecución, en este caso bash) con zshon si stdout está abierto en un terminal (no es un archivo / tubería / etc.).

sebasth
fuente