/etc/profile.d и "ssh -t"

Я хотел запустить скрипт на удаленной машине. Простое решение заключается в следующем:

ssh remote1 some-script

Это работает до тех пор, пока удаленный скрипт не захочет подключиться к другому удаленному компьютеру (remote2), который требует интерактивной аутентификации, как это (remote2 доступен только через remote1 в этом случае):

ssh remote1 "ssh remote2 some-script"

Решение проблемы заключается в использовании -t вариант для сш.

ssh -t remote1 "ssh remote2 some-script"

Это работает, но я получаю пробемы в случае, если я использую это (где some-script может выполнить дальнейшие команды ssh):

ssh -t remote1 some-script

Я обнаружил, что некоторые переменные среды не установлены, которые устанавливаются, когда я не использую -t вариант. Эти переменные окружения устанавливаются в сценариях /etc/profile.d, Я думаю, что эти сценарии не запускаются по какой-то причине, если использовать -t вариант, но запускаются, если я им не пользуюсь.

В чем причина этого? Есть ли способ обойти это? Я использую SUSE Linux (версия 10).

Изменить: я сделал некоторые дополнительные исследования. Я поместил несколько строк вывода в следующие места:

  • в одном файле в /etc/profile.d
  • в ~/.bash_profile (файла не было раньше)
  • в ~/.bashrc (файла не было раньше)

Затем я проверил несколько сценариев, какой вывод я получаю и в каком порядке (переменная окружения, которую я проверял, $PATH):

  • ssh remote1: profile.d, .bashrc, .bash_profile, $PATH ХОРОШО.
  • ssh -t remote1: profile.d, .bashrc, .bash_profile, $PATH ХОРОШО.
  • ssh remote1 echo '$PATH': только .bashrc, $PATH ХОРОШО.
  • ssh -t remote1 echo '$PATH': нет вывода скрипта. $PATH NOK.

Теперь я действительно не понимаю, что происходит. Если я запускаю интерактивную оболочку, все, кажется, работает нормально (хотя я нахожу странным, что ~/.bashrc включен до ~/.bash_profile). Если я запускаю неинтерактивную оболочку без -tСценарии профиля, кажется, не работают, но переменные среды установлены. Если я запускаю неинтерактивную оболочку с -t, тогда профили профилей не выполняются и переменные среды не устанавливаются. У кого-нибудь есть объяснение этому?

3 ответа

Решение

Я не нашел причину проблемы. Может быть, это специально для платформы (SLES 10 или вариант, который я использую). Я нашел обходной путь вместо этого:

ssh -t remote1 "/bin/bash --login -c some-script"

Это заставляет оболочку входа в систему, которая запускает скрипты профиля.

На все вопросы вы можете найти ответы в разделе "ПРИЗНАНИЕ" справочной страницы bash:

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

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

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

Как видите, интерактивные оболочки только источник .bashrcи часто .bash_profile будет получен оттуда, что объясняет порядок, который вы видите.

Очень часто эти файлы также имеют условие, чтобы анализировать только определенные разделы только для интерактивных оболочек ([[ $- == *i* ]]), что объясняет, почему некоторые части могут отсутствовать для неинтерактивных оболочек.

Разница между

ssh remote1 echo '$PATH'

а также

ssh -t remote1 echo '$PATH'

также объясняется на странице руководства bash:

Bash пытается определить, когда он запускается со своим стандартным входом, подключенным к сетевому соединению, как при выполнении демоном удаленной оболочки, обычно rshdили демон безопасной оболочки sshd, Если bash определяет, что он выполняется таким образом, он читает и выполняет команды из ~/.bashrc [Я предполагаю, что следует прочитать /etc/bash.bashrc] а также ~/.bashrc, если эти файлы существуют и доступны для чтения.

В первом примере bashsdin подключен к сетевому соединению, поэтому он работает ~/.bashrc, Во-вторых, его stdin исходит от псевдо-терминала, так что это не так.

Другие вопросы по тегам