`SSH <host>`это оболочка для входа, но` ssh <host> <command></command>`нет? </host></host>

2714
Ryan Lue

Я заметил, что когда я запускаю команду непосредственно на хосте SSH с использованием ssh <host> <command>синтаксиса, я вижу вывод, .bashrcно не вывод .bash_profile(или .profile).

Например, если я помещу следующую команду вверху обоих файлов,

echo $ 

и вручную источник .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в том, что бывший для оболочек входа в то время как последний для интерактивных, без входа в оболочках .

Я заключил следующее:

  1. ssh <host>только источники .bash_profile, в то время как
  2. ssh <host> <command>только источники .bashrc, что означает
  3. первая - это оболочка для входа, а вторая - нет.

Верны ли эти выводы? Почему ssh <host> <command>рассматривается как интерактивная оболочка без входа в систему? Разве SSH все еще не входит в удаленную машину для выполнения команды?

10
вывод `.bashrc`? Этот файл не должен производить никаких выходных данных. Любой вывод из `.bashrc` может сломать все инструменты, используя ssh в качестве транспорта. kasperd 7 лет назад 0
Справедливо. В этом случае пара строк в `.bashrc` выдавала ошибку, в то время как аналогичные строки в` .bash_profile` не были. Я воспользовался возможностью, чтобы исследовать несоответствие, прежде чем исправлять оскорбительные строки. Ryan Lue 7 лет назад 0

3 ответа на вопрос

11
Eric Renouf

OpenSSH (скорее всего, то, что вы используете) решает, создавать ли оболочку входа в систему или нет, и делает это только в том случае, если вы не запускаете определенную команду. От man ssh:

 If command is specified, it is executed on the remote host instead of a login shell. 

Таким образом, для сервера ssh это выбор реализации: хочет ли он создать оболочку входа или нет, и если вы даете команду на запуск, он этого не делает.

Хотя sshвход в систему и выполняется, но если вы выполняете команду и выходите из нее, на самом деле это гораздо больше похоже на создание оболочки для простого запуска этой команды, чем на получение среды входа. Кажется, учитывая это, что люди, пишущие OpenSSH, решили относиться к этому как к такой задаче.

Они создают неинтерактивную, не входящую в систему оболочку для выполнения команды, потому что это дух запуска команды в другом контексте / оболочке. Обычно, однако, неинтерактивные оболочки не будут автоматически источником, ~/.bashrcчто явно происходит здесь. bashна самом деле пытается помочь нам здесь. Из документов

Вызывается демоном удаленной оболочки

Bash пытается определить, когда он запускается со стандартным входом, подключенным к сетевому соединению, как при выполнении демоном удаленной оболочки, обычно rshd, или демоном защищенной оболочки sshd. Если Bash определяет, что он выполняется таким образом, он читает и выполняет команды из ~ / .bashrc, если этот файл существует и доступен для чтения. Он не будет делать это, если вызывается как sh. Параметр --norc можно использовать для запрета этого поведения, а параметр --rcfile можно использовать для принудительного чтения другого файла, но ни rshd, ни sshd обычно не вызывают оболочку с этими параметрами и не позволяют их указывать.

«... выполняется на удаленном хосте вместо оболочки входа в систему». Я не понимаю эту дихотомию. Команда выполняется ** на удаленном хосте ** вместо ** в оболочке входа ** или ** команда ** выполняется на удаленном хосте вместо ** оболочки входа **, выполняемой там ? Если первое, как оно или / или? (разве это обычно не _both? _) Если последний, он все еще выполняется в контексте оболочки _some_, не так ли? (интерактивный, не входящий в систему?) Итак, мой вопрос также о семантике - что означает «оболочка входа в систему», и почему OpenSSH должен быть разработан, чтобы не создавать ее для отдельных команд? Ryan Lue 7 лет назад 0
@RyanLue Каждый из различных «разновидностей» оболочек делает определенные задачи более легкими / более безопасными / оптимизированными и т. Д. Хотя выполнение `ssh` требует входа в систему, разработчики, по-видимому, решили, что при некоторых обстоятельствах, например, запрашивая выполнение команды и верните, не нужно / не извлекайте выгоду из дополнительных шагов, которые выполняет оболочка входа в систему, и поэтому они пропускают это. Так что, действительно, есть оболочка, которая запускается, я полагаю, в основном, для настройки среды, и поскольку оболочка не будет предоставлена ​​пользователю, который вошел в систему, они обрабатывают ее так, как если бы пользователь только что запустил новую оболочку для запуска этой среды. команда Eric Renouf 7 лет назад 0
«Так что, действительно, есть оболочка, которая запускается, я полагаю, в основном, для настройки среды ...» <но я просто экспериментировал с этим, и похоже, что `ssh `не наследует окружение какой-либо существующей оболочки входа в систему. Например, `$ ssh \ $ PATH` возвращает путь, как это было бы _without_ sourcing `.bash_profile` (или` .profile`, как бы) ... В практическом смысле, почему вы хотите обойти этот шаг? Ryan Lue 7 лет назад 0
«... разработчики, по-видимому, решили, что при некоторых обстоятельствах, например, при запросе на выполнение команды и возврате, не нужно / не нужно извлекать пользу из дополнительных шагов, которые выполняет оболочка входа в систему, и поэтому они пропускают это». ищу разъяснения / понимание этого выбора дизайна. Я определяю `PATH` в` .profile` - разве это не та вещь, которую вы хотели бы загрузить перед выполнением произвольной команды на удаленном хосте? Ryan Lue 7 лет назад 0
@RyanLue Я просто отредактировал свой ответ, чтобы попытаться понять, почему я думаю, что они сделали такой выбор Eric Renouf 7 лет назад 0
Спасибо! Но повторю: «Они создают неинтерактивную, не входящую в систему оболочку для выполнения команды», если это правда, то почему тогда получается источник .bashrc? ([`.bashrc` выполняется на интерактивных оболочках без входа в систему] (https://stackoverflow.com/a/415444/4865822), для записи.) Ryan Lue 7 лет назад 0
@RyanLue хороший улов, и ответ теперь обновляется, чтобы включить это тоже Eric Renouf 7 лет назад 0
Вот это да. Вы действительно прошли лишнюю милю там; Хотелось бы, чтобы у меня было больше одного голоса. Если вы чувствуете, что хотите выиграть несколько очков в Unix SE, [я пересыл этот вопрос туда] (https://unix.stackexchange.com/questions/374780/why-does-openssh-treat-ssh-host-command- как-нерегистрированная-оболочка). (Как вы думаете, это имеет какое-либо влияние на то, какие настройки относятся к `.bash_profile`, а какие относятся к` .bashrc`? Например, я использую `.bashrc`, чтобы убедиться, что терминал открывается в сеансе tmux с `tmux new -A`, но, естественно, предпочел бы, чтобы это не происходило из неинтерактивной оболочки ssh ...) Ryan Lue 7 лет назад 0
@RyanLue SE на самом деле не рекомендует кросс-постинг, поэтому я бы порекомендовал удалить этот или другой, и я думаю, что проблема, с которой вы столкнулись, заключается в том, почему многие bashrc имеют тесты, чтобы увидеть, являются ли они интерактивными или нет Eric Renouf 7 лет назад 0
@RyanLue Сервер Boks ssh различает использование ssh и может предоставлять разрешения для каждого из них. Удаленный вход в систему, удаленное выполнение, удаленное копирование. Может быть, это помогает понять, почему вы будете вести себя так, как вы описали. Удаленный вход в систему (интерактивное использование) может оказаться слишком сложным в среде с высоким уровнем безопасности. Openssh может быть ограничен использованием rbash / rksh и 'logout' в .bash_profile или chroot. bbaassssiiee 7 лет назад 1
3
zwol

, Почему это поведение лежит на более низкий уровне, чем оболочки: 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, но она есть, если вы когда-нибудь найдете.

1
Genaro Morales

Сначала вы должны увидеть различные типы, вы можете прочитать это:

https://unix.stackexchange.com/questions/170493/login-non-login-and-interactive-non-interactive-shells

Теперь, если вы откроете свой bashrc, вы увидите в начале это:

# If not running interactively, don't do anything [ -z "$PS1" ] && return 

Это означает, что в зависимости от того, как вы обращаетесь к системе, этот файл загружает код внутри или нет.

Хорошо, но это поднимает интересный вопрос: `.bashrc` может быть написан так, чтобы не быть источником, если он вызывается в неинтерактивном контексте (_i.e., _, Если нет« оператора запроса »/` $ PS1 переменная Но `сш `** явно не интерактивен **; то есть он не вызывает командную строку. Так почему же OpenSSH должен быть разработан для создания интерактивного приглашения без входа в систему (которое пытается получить исходный код `.bashrc`) для этого, казалось бы, неинтерактивного сценария использования? Ryan Lue 7 лет назад 0

Похожие вопросы