Почему удаленная команда SSH получает меньше переменных среды, чем при запуске вручную?
У меня есть команда, которая работает нормально, если я ssh к машине и запускаю ее, но не удается, когда я пытаюсь запустить ее с помощью удаленной команды ssh, например:
ssh user@IP <command>
Сравнение вывода "env" с использованием обоих методов приводит к различным средам. Когда я вручную захожу на компьютер и запускаю env, я получаю гораздо больше переменных окружения, чем при запуске:
ssh user@IP "env"
Есть идеи почему?
6 ответов
Существуют разные типы снарядов. Оболочка выполнения команды SSH - это неинтерактивная оболочка, тогда как обычная оболочка - это либо оболочка входа в систему, либо интерактивная оболочка. Описание следует из man bash:
Оболочка входа - это та, чей первый символ аргумента ноль - -, или тот, который начинается с опции --login. Интерактивная оболочка запускается без аргументов без опций и без опции -c, чьи стандартные входные данные и ошибки связаны с терминалами (как определено isatty(3)), или запускается с опцией -i. PS1 установлен, а $- включает i, если bash интерактивен, что позволяет сценарию оболочки или файлу запуска проверить это состояние. В следующих параграфах описывается, как bash выполняет свои файлы запуска. Если какой-либо из файлов существует, но не может быть прочитан, bash сообщает об ошибке. Тильды раскрываются в именах файлов, как описано ниже в разделе "Расширение тильды" в разделе "РАСШИРЕНИЕ". Когда bash вызывается как интерактивная оболочка для входа или как неинтерактивная оболочка с параметром --login, она сначала читает и выполняет команды из файла /etc/profile, если этот файл существует. После прочтения этого файла он ищет ~/.bash_profile, ~/.bash_login и ~/.profile в указанном порядке, а также читает и выполняет команды из первой, которая существует и доступна для чтения. Опция --noprofile может использоваться, когда оболочка запущена, чтобы запретить это поведение. Когда оболочка входа в систему закрывается, bash читает и выполняет команды из файла ~/.bash_logout, если он существует. Когда запускается интерактивная оболочка, которая не является оболочкой входа в систему, bash читает и выполняет команды из ~/.bashrc, если этот файл существует. Это может быть запрещено с помощью параметра --norc. Опция --rcfile file заставит bash читать и выполнять команды из файла вместо ~/.bashrc. Когда bash запускается неинтерактивно, например, для запуска сценария оболочки он ищет переменную BASH_ENV в среде, расширяет ее значение, если оно там появляется, и использует расширенное значение в качестве имени файла для чтения и выполнения., Bash ведет себя так, как будто была выполнена следующая команда: if [ -n "$BASH_ENV" ]; затем. "$BASH_ENV"; но значение переменной PATH не используется для поиска имени файла.
Как насчет поиска профиля перед запуском команды?
ssh user@host "source /etc/profile; /path/script.sh"
Возможно, вам будет лучше изменить это на ~/.bash_profile
, ~/.bashrc
или что угодно.
Среда оболочки не загружается при запуске удаленной команды ssh. Вы можете редактировать файл окружения ssh:
vi ~/.ssh/environment
Его формат:
VAR1=VALUE1
VAR2=VALUE2
Также проверьте конфигурацию sshd для параметра PermitUserEnvironment=yes.
У меня была похожая проблема, но в итоге я узнал, что ~/.bashrc - это все, что мне нужно.
Однако в Ubuntu мне пришлось прокомментировать строку, которая останавливает обработку ~/.bashrc:
#If not running interactively, don't do anything
[ -z "$PS1" ] && return
Просто экспортируйте переменные окружения, которые вы хотите, перед проверкой неинтерактивной оболочки в ~/.bashrc.
Я нашел простое решение этой проблемы - добавить исходный файл /etc/profile в начало файла script.sh, который я пытался запустить в целевой системе. В системах здесь это привело к тому, что переменные окружения, которые были необходимы для script.sh, были настроены так, как если бы они запускались из оболочки входа в систему.
В одном из предыдущих ответов было предложено использовать ~/.bashr_profile и т. Д. Я не тратил много времени на это, но проблема в том, что если вы используете ssh для другого пользователя в целевой системе, а не для оболочки исходной системы, из которой вы вошли, мне показалось, что это вызывает пользователя исходной системы. имя, которое будет использоваться для ~.