Что проверяет [-t 1]?

13

Я только что нашел способ начать, zshкогда я запускаю bashна Windows из

https://www.howtogeek.com/258518/how-to-use-zsh-or-another-shell-in-windows-10/ .

Рекомендуется добавить следующий код в конце .bashrc.

# Launch Zsh
if [ -t 1 ]; then
exec zsh
fi

Что [ -t 1 ]значит?

Это правда?

Тогда я могу просто сделать это?

exec zsh
Джин Квон
источник

Ответы:

14

[]это ярлык testкоманды.

По словам man test:

-t FD
Истинно, если FD - дескриптор файла, связанный с терминалом.

Поэтому, если вы запускаете bash в качестве интерактивной оболочки (терминал - см. Этот поток для объяснения терминологии), bash будет заменен на zsh.

Подробнее о .bash * файлах:

Когда bash вызывается как интерактивная оболочка входа в систему или как неинтерактивная оболочка с параметром --login , она сначала читает и выполняет команды из файла / etc / profile, если этот файл существует. После прочтения этого файла он ищет ~ / .bash_profile, ~ / .bash_login и ~ / .profile в указанном порядке, а также читает и выполняет команды из первой, которая существует и доступна для чтения. Опция --noprofile может использоваться, когда оболочка запущена, чтобы запретить это поведение.

При выходе из оболочки входа в систему bash читает и выполняет команды из файлов ~ / .bash_logout и /etc/bash.bash_logout, если файлы существуют.

Когда запускается интерактивная оболочка, которая не является оболочкой входа в систему , bash читает и выполняет команды из ~ / .bashrc , если этот файл существует. Это может быть запрещено с помощью параметра --norc. Опция --rcfile file заставит bash читать и выполнять команды из файла вместо ~ / .bashrc.

Комментарий Стефана Чазела:
обратите внимание, что оболочка может быть интерактивной, а stdout не является терминалом, а оболочка может быть неинтерактивной с терминалом на stdout (как в любое время, когда вы запускаете скрипт в терминале без перенаправления / передачи его вывода), и bashможет читать, .bashrcдаже когда он не интерактивный (например, ssh host cmdгде bashнаходится оболочка входа пользователя на хост или bash --login -c 'some code'). case $- in *i*)...правильный способ проверить, является ли оболочка интерактивной.

mrc02_kr
источник
4
Обратите внимание, что оболочка может быть интерактивной, а stdout не является терминалом, а оболочка может быть неинтерактивной с терминалом на stdout (как всякий раз, когда вы запускаете скрипт в терминале без перенаправления / передачи его вывода), и bashможет читать, .bashrcдаже если нет интерактивный (например, ssh host cmdгде bashнаходится оболочка входа пользователя на хост или bash --login -c 'some code'где находятся .bash_profileисточники .bashrc). case $- in *i*)...правильный способ проверить, является ли оболочка интерактивной.
Стефан
@ StéphaneChazelas хорошая мысль. Я буду содержать ваш комментарий в ответ
mrc02_kr
Существует ряд различных определений «интерактив». Если оболочка думает, что она интерактивная, то iона будет установлена ​​(и в современных оболочках, которые можно протестировать ifвместо использования case). Но во многих случаях используется только то, подключен ли к терминалу stdout (или stdin, или stderr ...).
Марк Рид
9

Команда test [ -t 1 ] проверяет, находится ли вывод bash на терминале. Цель этой строки - запустить zsh при открытии терминала, не нарушая другие способы использования bash. Но это сделано очень плохо.

Файл .bashrcчитается в трех случаях:

  • Когда bash выполняется как интерактивная оболочка, т.е. для запуска команд, набранных пользователем, а не для выполнения пакетных команд.
  • Когда bash - это неинтерактивная оболочка, которая запускается демоном RSH или SSH (обычно потому, что вы запускаете, ssh host.example.com somecommandа bash является вашей оболочкой входа в систему host.example.com).
  • Когда он вызывается явно, например, у пользователя .bash_profile( выбор файлов запуска bash немного странный ).

[ -t 1 ]плохой способ обнаружения интерактивных оболочек. Можно, но редко, запускать bash в интерактивном режиме со стандартным выводом, не выходя на терминал. Чаще встречается стандартный вывод на терминал в неинтерактивной оболочке; неинтерактивная оболочка не работает, .bashrcно, к сожалению, командные оболочки, вызываемые SSH, делают. Есть гораздо лучший способ: bash (и любая другая оболочка в стиле sh) предоставляет встроенный надежный метод для этого.

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

Поэтому «запустите zsh, если это интерактивная оболочка»

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

Но даже это не очень хорошая идея: это предотвращает открытие оболочки bash, что полезно, даже если вы используете zsh. Забудьте об этом сообщении в блоге и вместо этого просто настройте ярлык, который открывает терминал для запуска zsh вместо bash. Не делайте так, чтобы «всякий раз, когда вы открываете приложение Bash в Windows, оно теперь запускается с оболочкой Zsh»: когда вы хотите zsh, откройте приложение Zsh.

Жиль "ТАК - перестань быть злым"
источник
Для rsh/ sshи для интерактивной оболочки, это если это не оболочка входа в систему. Для оболочек входа в систему ( sshdне запускается неинтерактивная оболочка входа в систему, но вы можете сделать это с помощью ssh host exec bash -l), .bash_profileвместо этого читается. Также обратите внимание, что для rsh/ ssh, вы также должны $SHLVLбыть unset или 0.
Стефан
5

человек 1 тест :

-t FD

файловый дескриптор FD открывается на терминале

Ваш пример выполняется (в данном случае заменяет запущенный процесс bash) zshна on, если на терминале открыт stdout (не файл / pipe / etc).

sebasth
источник