Це питання, яке я збирався опублікувати тут кілька тижнів тому. Як і тердон , я зрозумів, що a .bashrc
використовується лише для інтерактивних оболонок Bash, тому не потрібно .bashrc
перевіряти, чи працює він в інтерактивній оболонці. Конфузно, що всі дистрибутиви, які я використовую (Ubuntu, RHEL та Cygwin), мали певний тип перевірки (тестування $-
чи $PS1
), щоб переконатися, що поточна оболонка є інтерактивною. Мені не подобається програмування культового культу, тому я почав розуміти мету цього коду в своєму .bashrc
.
Bash має спеціальний чохол для віддалених снарядів
Дослідивши проблему, я виявив, що віддалені снаряди трактуються по-різному. Хоча неінтерактивні оболонки Bash зазвичай не виконують ~/.bashrc
команди при запуску, особливий випадок робиться, коли оболонку викликає віддалений демон оболонки :
Bash намагається визначити, коли він працює з його стандартним входом, підключеним до мережевого з'єднання, як коли виконується віддаленим демоном оболонки rshd
, або захищеним демоном оболонки sshd
. Якщо Bash визначає, що його виконують таким чином, він зчитує та виконує команди з ~ / .bashrc, якщо цей файл існує та читається. Це не зробить цього, якщо викликати як sh
. --norc
Опція може бути використана для придушення такої поведінки, і --rcfile
опція може бути використана , щоб змусити інший файл , який буде лічений, але ні , rshd
ні sshd
взагалі посилатися на оболонку з цими опціями , або дозволити їм бути вказано.
Приклад
Вставте наступне на початку пульта .bashrc
. (Якщо ви .bashrc
отримаєте .profile
або .bash_profile
тимчасово відключіть це під час тестування):
echo bashrc
fun()
{
echo functions work
}
Виконайте такі команди локально:
$ ssh remote_host 'echo $- $0'
bashrc
hBc bash
- Ні вказує
i
на $-
те, що оболонка не інтерактивна .
- Немає провідних вказує
-
на $0
те, що оболонка не є оболонкою для входу .
Функції оболонки, визначені на пульті дистанційного керування, .bashrc
також можна виконувати:
$ ssh remote_host fun
bashrc
functions work
Я помітив, що ~/.bashrc
функція виділяється лише тоді, коли в якості аргументу вказана команда ssh
. Це має сенс: коли ssh
використовується для запуску звичайної оболонки входу, .profile
або .bash_profile
запускається (і .bashrc
отримується лише у тому випадку, якщо явно це зроблено одним з цих файлів).
Основна перевага, яку я можу побачити від отримання .bashrc
(неінтерактивної) віддаленої команди, полягає в тому, що функції оболонки можна запускати. Однак більшість команд у типовому .bashrc
випадку стосуються лише інтерактивної оболонки, наприклад, псевдоніми не розширюються, якщо оболонка не є інтерактивною.
Віддалені передачі файлів можуть не вдатися
Зазвичай це не проблема, коли rsh
або ssh
використовується для запуску інтерактивної оболонки входу або коли неінтерактивні оболонки використовуються для запуску команд. Тим НЕ менше, це може бути проблемою для таких програм, як rcp
, scp
і sftp
які використовують дистанційні оболонки для передачі даних.
Виявляється, що оболонка віддаленого користувача за замовчуванням (як Bash) неявно запускається при використанні scp
команди. На сторінці man не згадується про це - лише згадка, яка scp
використовується ssh
для передачі даних. Це призводить до того, що якщо .bashrc
містяться команди, які друкують до стандартного виводу, передача файлів буде невдалою , наприклад,
scp виходить з ладу без помилок .
Дивіться також цей пов'язаний звіт про помилки Red Hat від 15 років тому, scp перерви, коли в / etc / bashrc є команда echo (яка в кінцевому підсумку закрита як WONTFIX
).
Чому scp
і sftp
не вдається
SCP (захищена копія) та SFTP (протокол захищеної передачі файлів) мають власні протоколи для локального та віддаленого кінців для обміну інформацією про передані файли (файли). Будь-який несподіваний текст із віддаленого кінця (помилково) інтерпретується як частина протоколу, і передача не вдається. Відповідно до поширених запитань із книги про равликів
Часто трапляється, однак, є те , що є заяви в будь-якій системі або для кожного користувача файлів запуск оболонки на сервері ( .bashrc
, .profile
,
/etc/csh.cshrc
, .login
і т.д.) , які висновок текстові повідомлення на вході, призначені для читання людини (наприклад fortune
, echo "Hi there!"
, тощо).
Такий код повинен створювати вихід лише на інтерактивних логінах, якщо
tty
до входу додається стандартний вхід. Якщо він не зробить цей тест, він вставить ці текстові повідомлення там, де вони не належать: у цьому випадку, забруднюючи потік протоколу між scp2
/ sftp
і sftp-server
.
Причина файлів запуску оболонки взагалі актуальна - це те, що вона sshd
використовує оболонку користувача під час запуску будь-яких програм від імені користувача
(використовуючи, наприклад, / bin / sh -c "команду"). Це традиція Unix і має переваги:
- Звичайні налаштування користувача (псевдоніми команд, змінні середовища, umask тощо) діють при запуску віддалених команд.
- Поширена практика встановлення оболонки облікового запису на / bin / false для її відключення заважає власнику виконувати будь-які команди, якщо автентифікація все-таки випадково вдалася з якихось причин.
Деталі протоколу SCP
Для тих, хто цікавиться подробицями того, як працює SCP, я знайшов цікаву інформацію в розділі « Як працює протокол SCP», який містить деталі про Запуск scp з балакучими профілями оболонки на віддаленій стороні? :
Наприклад, це може статися, якщо ви додасте це до профілю оболонки на віддаленій системі:
відлуння ""
Чому він просто висить? Це відбувається з того, як scp
у вихідному режимі чекає підтвердження першого протокольного повідомлення. Якщо це не двійковий номер 0, він очікує, що це повідомлення про віддалену проблему і чекає, поки більше символів сформує повідомлення про помилку, поки не надійде новий рядок. Оскільки ви не надрукували ще один новий рядок після першого, ваш локальний scp
просто залишається в циклі, заблокований read(2)
. Тим часом, після оброблення профілю оболонки на віддаленій стороні, scp
в режимі мийки був запущений режим, який також блокується read(2)
, чекаючи бінарного нуля, що позначає початок передачі даних.
Висновок / TLDR
Більшість висловлювань у типовому варіанті .bashrc
корисні лише для інтерактивної оболонки - не під час виконання віддалених команд з rsh
або ssh
. У більшості таких ситуацій встановлення змінних оболонок, псевдонімів та визначення функцій не бажано - а друк будь-якого тексту до стандартного виходу є активно шкідливим при передачі файлів за допомогою таких програм, як scp
або sftp
. Вихід після перевірки того, що поточна оболонка не інтерактивна, є найбезпечнішою поведінкою для .bashrc
.