Как использовать SSH для запуска оболочки script на удаленном компьютере?

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

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

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

Есть ли способ запустить это с помощью plink/ssh?

Ответ 1

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

plink [email protected] -m local_script.sh

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

ssh [email protected] 'bash -s' < local_script.sh

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

Ответ 2

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

ssh [email protected] <<'ENDSSH'
#commands to run on remote host
ENDSSH

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

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

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

ssh [email protected] <<'ENDSSH'
#commands to run on remote host
ssh [email protected] <<'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 [email protected] <<-'ENDSSH'
    #commands to run on remote host
    ssh [email protected] <<-'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

Ответ 3

Кроме того, не забудьте избежать переменных, если вы хотите их забрать с целевого хоста.

Это уловило меня в прошлом.

Например:

[email protected]> ssh [email protected] "echo \$HOME"

выводит/home/user2

а

[email protected]> ssh [email protected] "echo $HOME"

выводит/home/user

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

[email protected]> ssh [email protected] "echo hello world | awk '{print \$1}'"

корректно выводит "привет".

Ответ 4

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

ssh [email protected] ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
  # commands to run on remote host
  echo $ARG1 $ARG2
ENDSSH

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

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

ssh user @host remote_command

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

ENV_VAR_1 = 'значение1' ENV_VAR_2 = 'значение2' bash -c 'echo $ENV_VAR_1 $ENV_VAR_2'

Это упрощает определение переменных перед запуском команды. В этом случае echo - наша команда, в которой мы работаем. Все перед echo определяет переменные среды.

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

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

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

Ответ 5

<hostA_shell_prompt>$ ssh [email protected] "ls -la"

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

Ответ 6

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

Ответ 7

Попробуйте запустить ssh [email protected] sh ./script.unx.

Ответ 8

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

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

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

Ответ 9

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

ssh [email protected] . /home/deploy/path/to/script.sh

Ответ 10

если вы хотите выполнить команду, как это temp='ls -a' echo $temp команда в '' приведет к ошибкам.

команда ниже решит эту проблему ssh [email protected] ''' temp='ls -a' echo $temp '''

Ответ 11

Ответ здесь (fooobar.com/questions/4973/...) прекрасно работает, если вы пытаетесь запустить скрипт на удаленной машине Linux, используя plink или ssh. Он будет работать, если в linux есть несколько строк.

** Однако, если вы пытаетесь запустить пакетный скрипт, расположенный на локальном linux/windows машина и ваш удаленный компьютер Windows, и он состоит из нескольких строк, используя **

plink [email protected] -m local_script.bat

не будет работать.

Будет выполнена только первая строка скрипта. Это, вероятно, ограничение plink.

Решение 1:

Чтобы запустить многострочный пакетный скрипт (особенно, если он относительно прост, состоящий из нескольких строк):

Если ваш оригинальный пакетный скрипт выглядит следующим образом

cd C:\Users\ipython_user\Desktop 
python filename.py

Вы можете объединить строки, используя "& amp;" разделитель следующим образом в вашем Файл local_script.bat: fooobar.com/questions/14050/...:

cd C:\Users\ipython_user\Desktop && python filename.py

После этого изменения вы можете запустить скрипт, как указано здесь @JasonR.Coombs: fooobar.com/questions/4973/... с:

'plink [email protected] -m local_script.bat'

Решение 2:

Если ваш пакетный скрипт относительно сложен, может быть лучше использовать пакетный скрипт скрипт, который инкапсулирует команду plink, а также следует, как указано здесь @Martin fooobar.com/questions/10625398/...:

rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N

rem Wait a second to let Plink establish the tunnel 
timeout /t 1

rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R

rem Kill the tunnel
taskkill /im plink.exe

Ответ 12

Этот bash-скрипт запускает ssh на целевой удаленной машине и запускает некоторую команду на удаленной машине, не забудьте установить ожидаемую часть перед запуском (на mac brew install expect)

#!/usr/bin/expect
set username "enterusenamehere"
set password "enterpasswordhere"
set hosts "enteripaddressofhosthere"
spawn ssh  [email protected]$hosts
expect "[email protected]$hosts password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"

Ответ 13

cat ./script.sh | ssh <user>@<host>

Ответ 14

ssh [email protected] ".~/.bashrc;/cd path-to-file/;.filename.sh"

настоятельно рекомендуется использовать исходный файл среды (.bashrc/.bashprofile/.profile). перед запуском чего-либо на удаленном хосте, потому что переменные окружения целевого и исходного хостов могут быть отключены

Ответ 15

Вы можете использовать runoverssh:

sudo apt install runoverssh
runoverssh -s localscript.sh user host1 host2 host3...

-s запускает локальный скрипт удаленно

Полезные флаги:
-g использовать глобальный пароль для всех хостов (запрос одного пароля)
-n использовать SSH вместо sshpass, полезно для аутентификации с открытым ключом

Ответ 16

Сначала скопируйте script на Machine B с помощью scp

[user @machineA] $scp/path/to/ script user @machineB:/home/user/path

Затем запустите script

[user @machineA] $ssh user @machineB "/home/user/path/ script"

Это будет работать, если вы предоставили исполняемый разрешение script.