Що перевіряє [-t 1]?


13

Я просто знайшов спосіб почати, zshколи запускаю bashWindows в

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
True, якщо 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 змусить bash читати та виконувати команди з файлу замість ~ / .bashrc.

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


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 shell, що корисно, навіть якщо ви використовуєте zsh. Забудьте про цю публікацію в блозі і замість цього просто налаштуйте ярлик, який відкриє термінал для запуску zsh замість bash. Не упорядковуйте речі так, що "щоразу, коли ви відкриєте програму Bash в Windows, вона тепер запуститься із оболонки Zsh": коли ви хочете zsh, відкрийте програму Zsh.


Для rsh/ sshта для інтерактивної оболонки це якщо вона не оболонка для входу. Для оболонок входу ( sshdне запускається неінтерактивна оболонка входу, але ви можете це зробити з ssh host exec bash -l), .bash_profileзамість цього читається. Також зауважте, що для rsh/ ssh, ви також повинні $SHLVLбути скасованими або 0.
Stéphane Chazelas

5

людина 1 тест :

-t FD

дескриптор файлу FD відкривається на терміналі

Ваш приклад виконує (замінює запущений процес, в цьому випадку bash) на zshна, якщо stdout відкритий на терміналі (не файл / труба / тощо).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.