Як я можу автоматично змінити каталог під час входу в ssh?


87

Я намагаюся перейти sshдо автоматичного переходу до певного каталогу під час входу. Я намагався дозволити цю поведінку працювати, використовуючи наступні директиви в ~/.ssh/config:

Host example.net
LocalCommand "cd web"

але кожного разу, коли я входжу, я бачу таке:

/bin/bash: cd web: No such file or directory

хоча хоча webв моєму домашньому довіднику певна папка. Навіть використання абсолютного шляху дає те саме повідомлення. Щоб було зрозуміло, якщо я набираю cd webпісля входу, я переходжу до потрібної папки.

Що я тут пропускаю?

Редагувати:

Різні комбінації цитат / абсолютних шляхів дають різні повідомлення про помилки:

LocalCommand "cd web"
/bin/bash: cd web: No such file or directory

LocalCommand cd web
/bin/bash: line 0: cd: web: No such file or directory

LocalCommand cd /home/gareth/web
/bin/bash: line 0: cd: /home/gareth/web: Input/output error

Це змушує мене думати, що котирування не повинно бути там, і що трапляється ще одна помилка.


9
LocalCommand запускається у вашій локальній системі, а не у віддаленій системі.
Стів Келет

Відповіді:


25

CD - це вбудована оболонка. LocalCommand виконується як:

/bin/sh -c <localcommand>

Те, що ви хочете зробити, насправді неможливо досягти через SSH; вам потрібно змінити оболонку якимось чином, наприклад, через bashrc / bash_profile.

<Редагування майже через десятиліття пізніше ...>

LocalCommandвсе одно не те, що ти хочеш. Це працює на вашій машині. Ти хочеш RemoteCommand. Щось подібне працювало для мене:

Host example.net
  RemoteCommand cd / && exec bash --login
  RequestTTY yes

1
Так, просто хотілося згадати те саме. Ви можете замість цього поставити cdкоманду ~/.bashrcна віддалений сервер.
vdboor

Це дратує. Як я вже згадував в іншому коментарі, на сервері є ряд імен хостів, і я хотів мати іншу поведінку, залежно від використання. Я думаю, неможливо визначити, що було використано з .bashrc?
Гарет

Це можливо, просто, мабуть, не доцільно. Щось на зразок заміни ssh невеликим скриптом оболонки або псевдонімом, який передає ім'я хоста як змінну, яку потрібно експортувати (a la "ssh -t user @ host 'export connhostname = host; bash --login'"). Але ви дійсно починаєте потрапляти на дуже дивну територію. Можливо, краще питання - ЧОМУ ви хочете такої поведінки?
BMDan

Чесно кажучи, це не така вже й велика справа. Я просто в ситуації, коли переважна більшість часу входу в цей сервер я пряму до одного з двох каталогів (залежно від того, яким хостом я користуюся)
Гарет

77

Це працює:

ssh server -t "cd /my/remote/directory; bash --login"

Щоб створити каталог, якщо він не існує:

ssh server -t "mkdir -p newfolder; cd ~/newfolder; pwd; bash --login"

Якщо ви не додали bashдо кінця шляху, ви виходите після cdзапуску команди. І якщо ви не додаєте, --loginто ваш ~/.profileне отриманий.


Це закінчує мене в правильному місці, з баш-підказкою. ідеально!
Пітер Ерліх

Це працює і для мене, але якщо я спробую використовувати його з ssh jump-host, це не працює. Я отримую закрите повідомлення про з'єднання.
Ріккардо

43
  1. Увійдіть у свій ящик
  2. Редагувати ~/.bash_profile
  3. В кінці файлу додати cd /path/to/your/destination
  4. Збережіть його та вийдіть
  5. Вихід з поля
  6. Ввійдіть ще раз, і ви повинні приземлитися /path/to/your/destination

3
На деяких машинах вам може знадобитися потрібно додати cd /path/to/your/destinationдо ~/.bashrcзамість до ~/.bash_profile. Результат повинен бути однаковим.
Маттіас

Це прекрасно працює завдяки - чи обмежений він лише моїм ідентифікатором користувача чи вплине також на інші входи користувачів?
hard_working_ant

@BabyGroot, якщо ви модифікуєте ~/.bash_profileабо ~/.bashrcце вплине лише на поточного користувача.
rubenvarela

5

Більш надійне рішення для випадку, коли потрібно ssh і переосмислити файл за замовчуванням .bashrc. Це корисно у випадках, коли віддалене середовище сервера має декілька докроотводчиків і використовується декількома користувачами.

alias ssh_myserver='ssh server_name -t "echo cd /path/to/desired/dir>/tmp/.bashrc_tmp; bash --rcfile /tmp/.bashrc_tmp"'

Більш детально:

  1. Перша команда створює .bashrc_tmpфайл у /tmpкаталозі на віддаленому сервері із вмістомcd /path/to/dir
  2. Наступна команда виконується за bashдопомогою конфігураційного файлу, визначеного на кроці 1. Це дозволяє перейти до потрібного режиму та придушити типовий режим .bashrc.
  3. Вся ця команда завершена як an alias, тому в командному рядку ssh client його можна викликати якssh_myserver

Creative ... доки у вас є писати perms в / tmp
smci

4

Ви ввімкнули цю директиву у своєму ssh-конфігурації?

PermitLocalCommand yes

Типовим для цього є no: у цьому випадку ваша LocalCommandдиректива буде ігнорована.

Або ви намагалися додати команду до свого .bashrcфайлу?


Ця директива встановлена, так (і я припускаю, що не бачив би повідомлення про помилку, якби не було). Проблема використання .bashrc полягає в тому, що сервер має різні імена хостів, і я хотів би, щоб різні імена хостів переводили в різні стартові каталоги
Гарет

Якщо кожне ім'я хоста не має іншої IP-адреси, сервер не може знати, яке ім'я хоста ви запитували. Хоча HTTP-запити забезпечують дружній заголовок Host: для ідентифікації запитуваного імені хоста, SSH-з'єднання не роблять.
Фоско

4

Тому я шукав багато веб-сайтів (stackoverflow, цей), але не знайшов того, що хотів. Я закінчила створення власного сценарію оболонки. Я його склеюю тут. Також ви можете скопіювати його у каталог у $ PATH.

#!/bin/bash
ssh -t <username@hostname> "cd ~/$1; exec \$SHELL --login"

Тож після цього. Я згоден:

connect <foldername>

Примітка. Можливо, вам потрібно буде вийти з системи та увійти знову після зміни змінної шляху


Я вважаю за краще це перед попередньою пропозицією, оскільки "$ SHELL" завжди діє, тоді як "bash" може бути не так. Також використання 'exec' є приємним штрихом.
Дейв

Подальше вдосконалення могло б забезпечити успіх "cd" - "cd ~ / $ 1 && exec ..."
Дейв

3

У вашому ~/.ssh/config:

LocalCommand echo '/home/%r/some/subdir' > /home/%r/.ssh/ssh_cd

Наприкінці вашого ~/.bashrc:

if [[ -f $HOME/.ssh/ssh_cd ]]
then
    cd $(<$HOME/.ssh/ssh_cd)
    # uncomment the line below and the file will be removed so the cd won't work
    # unless the file is regenerated since you may not want this to operate for
    # non-ssh logins or for ssh logins that you want to function differently
    # rm $HOME/.ssh/ssh_cd
fi

Я спробував це зробити за допомогою змінної передачі, в тому числі з експортованою змінною, але ці команди запускаються в різних оболонках.

Під час тестування того, що ви намагалися зробити, до речі, я не отримав помилку, коли використовував неописаний абсолютний шлях. Я додав ; pwdв кінці команди і відображається правильний каталог, однак каталог, в якому я опиняюсь, є ~. У cdфайлах запуску оболонки немає команд. Я спробував покласти інший cd somedir; pwdв ~/.ssh/rc(з іншого все ще на місці). configКоманда виконується до того , як MOTD видається і rcвидається команда згодом, але до оболонки файлів запуску джерел. Отже, знову ж таки, це відбувається в іншій оболонці.

Спробуйте техніку передачі файлів і повідомте мені, чи працює вона для вас.


2

Ви пробували це без цитат навколо нього? Єдині приклади, які я бачив, не мають їх, тому у них може бути спроба виконання cd \ web як команди.


Гаразд, видалення лапок здається, що це допомагає, але у мене все ще є помилки (див. Відредагований пост)
Гарет

1

Ви також можете спробувати це за допомогою параметра -t:

ssh server -t "cd /my/remote/directory; bash"

1

Спробуйте використовувати RemoteCommandнатомість, наприклад

Host myhost
  HostName IP
  User ubuntu
  IdentityFile ~/.ssh/id_rsa
  RemoteCommand cd web; $SHELL -il

RemoteCommand: Вказує команду для виконання на віддаленій машині після успішного підключення до сервера. ( man ssh_config)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.