Как использовать SSH для запуска сценария оболочки на удаленной машине? - PullRequest
1121 голосов
/ 20 ноября 2008

Мне нужно запустить скрипт оболочки (windows / Linux) на удаленной машине.

У меня настроен SSH как на машине A, так и на B. Мой сценарий находится на машине A, которая будет выполнять часть моего кода на удаленной машине, машине B.

Локальный и удаленный компьютеры могут быть системами на базе Windows или Unix.

Есть ли способ запустить это, используя plink / ssh?

Ответы [ 13 ]

1102 голосов
/ 29 апреля 2010

Если компьютер A представляет собой Windows-систему, вы можете использовать Plink (часть PuTTY ) с параметром -m, и он будет выполнять локальный скрипт на удаленном сервере.

plink root@MachineB -m local_script.sh

Если машина A является системой на основе Unix, вы можете использовать:

ssh root@MachineB 'bash -s' < local_script.sh

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

561 голосов
/ 06 октября 2010

Это старый вопрос, и ответ Джейсона работает нормально, но я хотел бы добавить это:

ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH

Это также можно использовать с командами su и, которые требуют ввода пользователем. (обратите внимание, ' избежал наследственности)

Редактировать: так как этот ответ продолжает получать бит трафика, я бы добавил еще больше информации к этому замечательному использованию heredoc:

Вы можете вкладывать команды с этим синтаксисом, и это единственный способ, которым кажется, что вложение работает (в здравом смысле)

ssh user@host <<'ENDSSH'
#commands to run on remote host
ssh user@host2 <<'END2'
# Another bunch of commands on another host
wall <<'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.secureftp-test.com <<'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH

На самом деле вы можете общаться с некоторыми службами, такими как telnet, ftp и т. Д. Но помните, что heredoc просто отправляет stdin как текст, он не ждет ответа между строками

Редактировать: Я только что узнал, что вы можете сделать отступ внутри вкладок , если вы используете <<-END!

ssh user@host <<-'ENDSSH'
    #commands to run on remote host
    ssh user@host2 <<-'END2'
        # Another bunch of commands on another host
        wall <<-'ENDWALL'
            Error: Out of cheese
        ENDWALL
        ftp ftp.secureftp-test.com <<-'ENDFTP'
            test
            test
            ls
        ENDFTP
    END2
ENDSSH

(думаю, это должно сработать)

Также см. http://tldp.org/LDP/abs/html/here-docs.html

232 голосов
/ 20 ноября 2008

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

Это застало меня в прошлом.

Например:

user@host> ssh user2@host2 "echo \$HOME"

распечатывает / home / user2

, а

user@host> ssh user2@host2 "echo $HOME"

распечатывает / home / user

Другой пример:

user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"

правильно печатает "привет".

143 голосов
/ 09 сентября 2011

Это расширение ответа YarekT для объединения встроенных удаленных команд с передачей переменных ENV с локального компьютера на удаленный хост, чтобы вы могли параметризовать свои сценарии на удаленной стороне:

ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote host
  echo $ARG1 $ARG2
ENDSSH

Я нашел это исключительно полезным, сохранив все это в одном скрипте, чтобы он был очень удобочитаемым и поддерживаемым.

Почему это работает. ssh поддерживает следующий синтаксис:

ssh user @ host remote_command

В bash мы можем указать переменные среды, которые нужно определить до запуска команды в одной строке, например:

ENV_VAR_1 = 'value1' ENV_VAR_2 = 'value2' bash -c 'echo $ ENV_VAR_1 $ ENV_VAR_2'

Это позволяет легко определять переменные перед выполнением команды. В этом случае echo - наша команда, которую мы выполняем. Все до echo определяет переменные окружения.

Итак, мы объединяем эти две функции и ответ YarekT, чтобы получить:

ssh user @ host ARG1 = $ ARG1 ARG2 = $ ARG2 'bash -s' << 'ENDSSH' ... </p>

В этом случае мы устанавливаем ARG1 и ARG2 в локальные значения. Отправка всего после user @ host как remote_command. Когда удаленный компьютер выполняет команду ARG1 и ARG2 устанавливаются локальные значения, благодаря локальной оценке командной строки, которая определяет переменные среды на удаленном сервере, а затем выполняет команду bash -s с использованием этих переменных. Вуаля.

100 голосов
/ 20 ноября 2008
<hostA_shell_prompt>$ ssh user@hostB "ls -la"

Это запросит у вас пароль, если только вы не скопировали открытый ключ пользователя hostA в файл author_keys в каталоге пользователя .ssh. Это позволит проводить аутентификацию без пароля (если она принята в качестве метода авторизации в конфигурации сервера ssh)

26 голосов
/ 26 января 2011

Я начал использовать Fabric для более сложных операций. Fabric требует Python и пару других зависимостей, но только на клиентском компьютере. Сервер должен быть только ssh-сервером. Я считаю, что этот инструмент гораздо более мощный, чем сценарии оболочки, переданные SSH, и стоит того, чтобы его настроить (особенно если вам нравится программирование на Python). Fabric обрабатывает выполняемые сценарии на нескольких хостах (или хостах определенных ролей), помогает упростить идемпотентные операции (такие как добавление строки в скрипт конфигурации, но не, если она уже есть), и позволяет создавать более сложную логику (такую ​​как Python) язык могу предоставить).

10 голосов
/ 19 декабря 2009

Попробуйте запустить ssh user@remote sh ./script.unx.

9 голосов
/ 20 ноября 2008

Предполагая, что вы хотите сделать это автоматически с «локального» компьютера, без ручного входа на «удаленный» компьютер, вы должны посмотреть на расширение TCL, известное как Expect, оно разработано именно для такой ситуации. Я также предоставил ссылку на скрипт для входа / взаимодействия через SSH.

https://www.nist.gov/services-resources/software/expect

http://bash.cyberciti.biz/security/expect-ssh-login-script/

2 голосов
/ 10 ноября 2018

Я использую этот для запуска сценария оболочки на удаленной машине (проверено на / bin / bash):

ssh deploy@host . /home/deploy/path/to/script.sh
1 голос
/ 21 сентября 2018

если вы хотите выполнить такую ​​команду temp=`ls -a` echo $temp команда в `` вызовет ошибки.

команда ниже решит эту проблему ssh user@host ''' temp=`ls -a` echo $temp '''

...