У меня есть скрипт, который выглядит примерно так:
ssh host command1
scp file1 host:/tmp
ssh host command2
Есть ли способ объединить их все в один ssh/scp
вызов? Проблема, с которой я столкнулся, заключается в объединении копирования файлов с выполнением команд, что должно быть сделано попеременно. Надеялся на что-то вроде:
ssh_sometool host -c command1 -cp file1 /tmp -c command2
Дело не в синтаксисе (я мог бы написать такую функцию), а во всем, что происходит в рамках одной ssh
сессии.
решение1
Прежде всего, нет простого или стандартного способа сделать то, что вы хотите. Кроме того, позвольте мне прояснить:нет возможности сделать то, что вы хотите, с помощью клиента SSH по умолчанию.
Есть очень старая вилкаssh-xfer. Обратите внимание, что даже разработчики этого инструмента подчеркивают, что их решение "хакерское" и действительно старое, поэтому вам не следует его использовать. Последняя версия SSH, которая была пропатчена для использования с этим инструментом, это OpenSSH-3.8.1p1
(в Arch Linux текущая версия - OpenSSH_7.6p1
).
Если для вас важно, чтобы все работало быстро, сводя к минимуму количество подключений/рукопожатий между хостами, вы можете рассмотреть какие-либо инструменты подготовки/оркестровки.Ансиблькажется, это самый простой способ выполнить задачу без особой дополнительной настройки,Сольможет быть самым быстрым.
В любом случае, и Ansible, и Salt используют дополнительные соединения для работы, и я не уверен, что вы что-то выиграете с точки зрения производительности, используя их вместо комбинации ssh/scp.
ОБНОВЛЕНИЕ: Если вам нужно загрузить и извлечь много файлов с выполнением дополнительных скриптов между этими передачами, то практически любой инструмент подготовки (Chef, Puppet, Salt, Ansible) справится с этой задачей быстрее, чем простой ssh/scp.
решение2
SSH позволяет иметь сеанс активным некоторое время после того, как вы отключились, так что вам не придется инициировать соединение в следующий раз. Вот параметры конфигурации ssh, чтобы включить это:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 30
ControlMaster
позволяет совместно использовать несколько сеансов через одно сетевое соединение. Если установлено значение auto
, каждая новая попытка проверяет, существует ли соответствующее соединение, и либо использует его, либо создает новое соединение.
ControlPath
указывает путь, где хранятся соединения.Убедитесь, что этот путь существует!То есть создайте каталог (Розеткиздесь, но назовите его как хотите) вручную.
ControlPersist
указывает, как долго соединение будет существовать после отключения. Принимает время в секундах.
Для получения дополнительных пояснений по параметрам используйте man ssh_config
.
После того, как вы добавите их в свой файл ~/.ssh/config
, для этих трех команд будет открыт только один сеанс.
На моем компьютере это дает пятикратное ускорение: 100 последовательных подключений к какому-либо (близлежащему) хосту обрабатываются за 30 секунд без постоянных сеансов и всего за 5-6 секунд с ними.
PS Иногда (например, если вы сменили сеть) ваши существующие ssh-соединения рвутся, а новые не устанавливаются, так как файл с соединением существует. В этом случае просто зайдите ~/.ssh/sockets
и удалите нужный файл вручную.
решение3
Вы можете присоединиться и передать все свои файлы через стандартный ввод SSH и получить их в своем удаленном сеансе, я имею в виду что-то вроде этого:
tar -cf - file1 file2 | ssh host 'TDIR=`mktemp -d`; tar -xf - -C "$TDIR"; cat "$TDIR/file1"; command1; command2 ...'
- Команда
cat "$TDIR/file1"
— это всего лишь пример того, как получить доступ к полученным файлам; - Используйте tar с ключом -j или -J как на локальной, так и на удаленной стороне для передачи сжатых файлов;
- Вы можете поместить все свои команды в скрипт bash, включить его в свой архив и выполнить на удаленной стороне, например:
...tar -xf - -C "$TDIR"; bash "$TDIR/script.sh"'
решение4
В вашем сценарии, как только первая строка начинается...
ssh host command1
Выполнение передается ssh + ваша вторая команда (scp) будет запущена только после завершения command1. Один из способов заставить их работать параллельно — это перевести каждую задачу в фоновый режим, например...
ssh host command1 &
scp file1 host:/tmp &
ssh host command2 &
Теперь все три задачи выполняются в фоновом режиме одновременно.