Я хотел запустить сценарий на удаленной машине. Вот простое решение:
ssh remote1 some-script
Это работает до тех пор, пока удаленный сценарий не захочет подключаться к другому удаленному компьютеру (remote2
), который требует интерактивной аутентификации, такой как этот (remote2
доступен только через remote1
в таком случае):
ssh remote1 "ssh remote2 some-script"
Решение проблемы - использовать -t
вариант для ssh.
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
, то сценарии профиля не запускаются и переменные среды не устанавливаются. У кого-нибудь есть объяснения по этому поводу?
Разница между
ssh remote1 echo '$PATH'
и
ssh -t remote1 echo '$PATH'
также объясняется на странице руководства bash:
Bash пытается определить, когда он запускается со своим стандартным вводом, подключенным к сетевому соединению, как при выполнении удаленным демоном оболочки, обычно
rshd
, или демон безопасной оболочкиsshd
. Если bash определяет, что он запускается таким образом, он читает и выполняет команды из~/.bashrc
[Я полагаю, что следует прочитать/etc/bash.bashrc
] и~/.bashrc
, если эти файлы существуют и доступны для чтения.
В первом примере bash
stdin подключен к сетевому соединению, поэтому он запускается ~/.bashrc
. Во втором случае его стандартный ввод поступает от псевдотерминала, поэтому это не так.
Причины проблемы не нашел. Возможно, это специфично для платформы (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* ]]
), что объясняет, почему некоторые части могут отсутствовать в неинтерактивных оболочках.