/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
, если эти файлы существуют и доступны для чтения.
В первом примере bash
sdin подключен к сетевому соединению, поэтому он работает ~/.bashrc
, Во-вторых, его stdin исходит от псевдо-терминала, так что это не так.