Я заметил, что когда я запускаю команду непосредственно на хосте SSH с использованием ssh <host> <command>
синтаксиса, я вижу вывод, .bashrc
но не вывод .bash_profile
(или .profile
).
Например, если я помещу следующую команду в верхней части обоих файлов,
echo ${BASH_SOURCE[0]}
и вручную источник .bash_profile
(какие источники .bashrc
в свою очередь), я посмотрю
$ . .bash_profile
.bash_profile
.bashrc
Это тот же вывод, который я вижу, если я подключаюсь к этому компьютеру удаленно через SSH, используя ssh <host>
форму команды. (И если я .bash_profile
временно уложу в другое место, ни одна из этих строк не будет отражена.)
Однако, если я выполню команду непосредственно на удаленной машине в ssh <host> <command>
форме ssh
, то результат будет выглядеть следующим образом:
$ ssh <host> echo foo
/home/rlue/.bashrc
foo
Я понимаю, что разница между .bash_profile
и .bashrc
в том , что бывший для оболочек входа в то время как последний для интерактивных, без входа в оболочках .
Я заключил следующее:
ssh <host>
только источники.bash_profile
, в то время какssh <host> <command>
только источники.bashrc
, что означает- первая - это оболочка для входа, а вторая - нет.
Верны ли эти выводы? Почему ssh <host> <command>
рассматривается как интерактивная оболочка без входа в систему? Разве SSH все еще не подключается к удаленной машине, чтобы выполнить команду?
.bashrc
? Этот файл не должен выдавать никаких результатов. Любые выходные данные.bashrc
могут сломать все инструменты, использующие ssh в качестве транспорта..bashrc
выдает ошибку, в то время как аналогичные строки.bash_profile
не были. Я воспользовался возможностью, чтобы исследовать несоответствие, прежде чем исправлять оскорбительные строки.Ответы:
OpenSSH (скорее всего, то, что вы запускаете) решает, создавать ли оболочку входа или нет, и делает это только в том случае, если вы не запускаете определенную команду. От
man ssh
:Таким образом, для сервера ssh это выбор реализации: хочет ли он создать оболочку входа или нет, и если вы даете команду на выполнение, это не так.
Хотя
ssh
вход в систему и выполняется, но если вы выполняете команду и завершаете работу, на самом деле это гораздо больше похоже на создание оболочки для простого запуска этой команды, чем на получение среды входа. Кажется, учитывая это, что люди, пишущие OpenSSH, решили относиться к этому как к такой задаче.Они создают неинтерактивную, не входящую в систему оболочку для выполнения команды, потому что это дух запуска команды в другом контексте / оболочке. Обычно, однако, неинтерактивные оболочки не будут автоматически источником,
~/.bashrc
что явно происходит здесь.bash
на самом деле пытается помочь нам здесь. Из документовисточник
ssh
и требует входа в систему, разработчики, по-видимому, решили, что при некоторых обстоятельствах, например, запрашивая выполнение команды и возвращение, делают нет необходимости / выгоды от дополнительных шагов, которые выполняет оболочка входа в систему, и поэтому они пропускают это. Так что, действительно, есть оболочка, которая запускается, я полагаю, в основном, для настройки среды, и поскольку оболочка не будет предоставлена пользователю, который вошел в систему, они обрабатывают ее так, как если бы пользователь только что запустил новую оболочку для запуска этой среды. командаssh <host> <command>
она не наследует среду какой-либо существующей оболочки входа в систему. Например,$ ssh <host> \$PATH
возвращает путь таким, каким он был бы без источников.bash_profile
(или.profile
как бы) ... В практическом смысле, почему вы хотите обойти этот шаг?PATH
ин.profile
- это не то, что именно такого рода вещи вы хотите загружен перед запуском произвольной команды на удаленном хосте?Почему такое поведение лежит на более низкий уровне , чем оболочки:
ssh host
(далее «Войти оболочки» случай) использует псевдотерминал на удаленном хосте, для связи междуsshd
процессом сервера и оболочкой;ssh host command
использует трубы междуsshd
иcommand
, вместо. Псевдотерминалы необходимы для интерактивного использования интерпретатора команд, такого как оболочка, или режима « read-eval-print » языка сценариев; они реализуют множество удобных для человека функций, таких как возможность опровергать опечатки. Но они имеют больше накладных расходов и (в зависимости от конфигурации) не позволяют произвольным данным проходить без изменений, поэтому SSH избегает их использования, когда взаимодействие не происходит.Иногда команда SSH / эвристика команд не понимает этого; он может быть изменён с помощью
-t
и-T
переключателей. Например, чтобы войти на удаленную машину и немедленно подключить приостановленныйscreen
сеанс, вам нужно сделать этоssh -t host screen -R
;ssh host screen -R
заставитscreen
жаловаться, что не подключен к терминалу. Я не могу вспомнить ситуацию, когда вы действительно захотите использовать-T
, но она есть, если вы когда-нибудь найдете.источник
Сначала вы должны увидеть различные типы, вы можете прочитать это:
/unix/170493/login-non-login-and-interactive-non-interactive-shells
Теперь, если вы откроете свой bashrc, вы увидите в начале это:
Это означает, что в зависимости от того, как вы обращаетесь к системе, этот файл загружает код внутри или нет.
источник
.bashrc
может быть написан так, чтобы не быть источником, если он вызывается в неинтерактивном контексте ( т. Е. Если нет «быстрой инструкции» /$PS1
переменной). Ноssh <host> <command>
это определенно не интерактивный ; то есть, он не поднимет командную строку. Так почему же OpenSSH должен быть создан для создания интерактивного приглашения без входа в систему (которое пытается получить источник.bashrc
) для этого, казалось бы, неинтерактивного сценария использования?