Как написать bash-скрипт, который входит в систему на другом компьютере, чтобы что-то делать?

11

Можно ли написать сценарий Bash, что

  1. будет запущен с машины A, войдет в систему на другой машине B с помощью ssh (обе машины A и B будут Linux-машинами),
  2. копирует некоторые файлы на компьютер B
  3. запускает скрипт Python для данного компьютера на данном компьютере.
  4. передает результаты обратно на машину A
  5. выходит из машины Б.

Это технически выполнимо?

Aufwind
источник

Ответы:

15

Конечно это выполнимо:

scp file user@host:
ssh user@host path_to_script
scp user@host:file_to_copy ./

и это все...

Но есть одна проблема: вам будет предложено ввести пароль три раза. Чтобы избежать этого, вы можете генерировать ssh-ключи и авторизовать пользователей по этим ключам.

Чтобы сгенерировать ключи ssh ssh-keygen -t rsa, ответьте на вопросы и скопируйте открытый ключ на удаленный хост (компьютер B) в ~/.ssh/authorized_keysфайл. Закрытый ключ должен быть сохранен ~/.ssh/id_rsaна локальном компьютере (A).

постоянный репер
источник
Если открытые ключи не являются опцией, вы можете сделать что-то грубое, чтобы минимизировать запросы пароля, такие какcat file | ssh user@host 'cat > /destination/of/file; /path/to/script &>/dev/null; cat results' > /destination/of/results
Патрик
Если вы хотите использовать пароль, вы всегда можете использовать пул соединений OpenSSH, определив ControlMaster=yesи ControlPath=/path/to/socketfile, а затем запустить одно соединение ssh -fдля запуска фонового ssh. Скажите всем последующим соединениям SSH использовать один и тот же файл сокета.
Jsbillings
4

Я могу сделать все в одном sshподключении / сеансе:

ssh user@host "cat > remote_dst; command; cat remote_src" < local_src > local_dst

Эта:

  1. Копирует local_srcв remote_dst,
  2. Выполняет command,
  3. Копирует remote_srcв local_dst.

Но если commandпишет дальше stdout, результат также будет в local_dst. Если commandчитает входные данные stdin, он получит и EOF.

jfg956
источник
3

Хотя вы можете сделать это внутри одного сеанса SSH, немного сложнее объединить копирование файлов с запущенными командами.

Самый простой способ решить эту задачу - запустить отдельные сеансы SSH для трех операций:

rsync -a inputs/ machineB:inputs/
ssh machineB 'some command -i inputs -o outputs'
rsync -a machineB:outputs/ outputs/

Это требует аутентификации на machineB три раза. Рекомендованный способ избежать многократной аутентификации - это использовать средство совместного использования соединений в современных версиях OpenSSH: запустить главное соединение с B раз и навсегда и автоматически подключить SSH к этому главному соединению. Добавьте ControlMaster autoи ControlPathстроку к вашему~/.ssh/config , затем запустите мастер-соединение в фоновом режиме, затем выполните свои задачи.

ssh -fN machineB                         # start a master connection in the background
# Subsequent connections will be slaves to the existing master connection
rsync -a inputs/ machineB:inputs/
ssh machineB 'some command -i inputs -o outputs'
rsync -a machineB:outputs/ outputs/

Вместо того, чтобы использовать scp или rsync для копирования файлов, может быть проще смонтировать удаленную файловую систему под SSHFS . Между прочим, это позаботится о настройке мастер-соединения (при условии, что вы настроили ~/.ssh/configкак указано выше).

mkdir /net/machineB
sshfs machineB: /net/machineB
cp -Rp inputs /net/machineB/
ssh machibeB 'some command -i inputs -o outputs'
cp -Rp /net/machineB/outputs .
Жиль "ТАК - перестань быть злым"
источник