`ssh <host>` - оболонка для входу, але `ssh <host> <command>` ні?


12

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

Я зробив висновок про наступне:

  1. ssh <host>лише джерела .bash_profile, поки
  2. ssh <host> <command>лише джерела .bashrc, що означає
  3. перший - оболонка для входу, а остання - ні.

Чи правильні ці висновки? Чому ssh <host> <command>трактується як інтерактивна оболонка без входу? Чи SSH все ще не входить у віддалену машину для виконання команди?


вихід .bashrc? Цей файл не повинен давати жодного результату. Будь-який вихід з .bashrcможе зламати всі інструменти, використовуючи ssh як їх транспорт.
kasperd

Досить справедливо. У цьому випадку кілька рядків у .bashrcпрогравали помилку, в той час як подібні лінії в .bash_profileних не були. Я скористався можливістю розслідувати невідповідність перед тим, як виправити кривдні лінії.
Ryan Lue

Відповіді:


12

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


"... він виконується на віддаленому хості замість оболонки входу." Я не розумію цієї дихотомії. Чи команда виконується на віддаленому хості, а не в оболонці для входу , або команда виконується на віддаленому хості, а не оболонці входу ? Якщо перший, як це / або? (чи не нормально це обидва? ) Якщо останній, він все ще виконується в контексті якоїсь оболонки, чи не так? (інтерактивний, не вхідний?) Тому моє запитання також стосується семантики - що означає "оболонка входу", і чому OpenSSH буде розроблений не для створення однієї команди?
Райан Люе

@RyanLue Різні "аромати" оболонок роблять певні завдання простішими / безпечнішими / оптимізованішими тощо. Хоча при виконанні операції sshпотрібен логін, реалізатори, мабуть, вирішили, що за певних обставин, наприклад, попросивши його виконати команду і повернутися, зробіть не потрібно / користь від додаткових кроків, які виконує оболонка входу, і вони пропускають це. Так що дійсно є оболонка, яку запускають, я припускаю, що головним чином налаштовувати середовище, і оскільки оболонка не буде надаватися користувачеві, який увійшов у систему, вони вважають, що користувач тільки що запустив нову оболонку для запуску цього команда
Ерік Реноф

"Отже, дійсно є оболонка, яку запускають, я припускаю, що головним чином налаштовувати середовище ..." <, але я просто експериментував з цим, і, здається, ssh <host> <command>він не успадковує оточення жодної існуючої оболонки входу. Наприклад, $ ssh <host> \$PATHповертає шлях таким, яким він був би без джерела .bash_profile(або .profile, як би це не було) ... У практичному розумінні чому б ви хотіли обійти цей крок?
Райан Люе

"... реалізатори, мабуть, вирішили, що за певних обставин, наприклад, попросивши його виконати команду та повернути, не потрібно / скористатися додатковими кроками, які виконує оболонка входу, і вони пропускають це". <також, спеціально шукаючи роз'яснення / розуміння цього вибору дизайну. Я визначаю мій PATHін .profile- це не те, що саме такого роду речі ви хочете завантажений перед запуском довільної команди на віддалений хост?
Райан Люе

1
@RyanLue ssh-сервер Boks розрізняє різні способи використання ssh і може надавати дозволи для кожного. Віддалене вхід, віддалене виконання, віддалене копіювання, можливо, це допомагає зрозуміти, чому б ви мали поведінку, яку ви описуєте. Віддалене вхід (інтерактивне використання) може бути занадто великим, щоб вимагати в умовах високої безпеки. Openssh можна обмежити за допомогою rbash / rksh та 'logout' у .bash_profile або chroot.
bbaassssiiee

4

Чому така поведінка лежить на більш низький рівень , ніж оболонки: ssh host(далі «Увійти оболонки» випадок) використовує псевдотермінал на віддалений хост, для зв'язку між sshdпроцесом сервера і оболонкою; ssh host commandвикористовує труби між sshdі command, замість цього. Псевдотермінали необхідні для інтерактивного використання командного інтерпретатора, такого як оболонка, або режиму " читання-еваль-друк " мови сценаріїв; вони реалізують купу зручних для людини функцій, таких як можливість зворотного простору над друкарськими помилками. Але вони мають більше накладних витрат (залежно від конфігурації) не дозволяють довільним даним проходити через немодифіковані, тому SSH уникає їх використання, коли взаємодія не відбуватиметься.

Іноді команда SSH / евристична команда не відповідає цьому неправильно; це може бути переопрацьовано -tі -Tперемикачами. Наприклад, щоб увійти до віддаленої машини та негайно приєднати призупинений screenсеанс, вам потрібно це зробити ssh -t host screen -R; ssh host screen -Rвикличе screenскарги на не підключення до терміналу. Я не можу придумати ситуацію, коли ви насправді хочете використовувати -T, але це є, якщо ви коли-небудь знайдете її.


1

Спочатку вам потрібно переглянути різні типи, ви можете прочитати це:

/unix/170493/login-non-login-and-interactive-non-interactive-shells

Тепер, якщо ви відкриєте bashrc, ви побачите на початку це:

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

Це означає, що залежно від способу доступу до системи цей файл завантажує код всередину чи ні.


Гаразд, але це викликає цікаве запитання: .bashrcможе бути написане так, щоб не отримати джерело, якщо воно викликається в неінтерактивному контексті ( тобто, якщо немає "оперативного заяви" / $PS1змінної). Але ssh <host> <command> це, безумовно, неінтерактивна ; тобто не викликає командного рядка. То чому б OpenSSH був розроблений для створення інтерактивного запиту без входу (той, який намагається створити джерело .bashrc) для цього, здавалося б, неінтерактивного випадку використання ??
Райан Люе
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.