#bash #ssh #rsync
#bash #ssh #rsync
Вопрос:
Я создал скрипт bash для переноса сайтов и баз данных с одного сервера на другой: алгоритм:
- Проанализируйте
.pgpass
файл, чтобы создать отдельные дампы для всех указанных Postgres db. - Загрузите указанные дампы на другой сервер через
rsync
. - Загрузите кучу папок, связанных с каждой базой данных, на другой сервер, также через rsync.
Поскольку базы данных и папки имеют одинаковые имена, сценарий может предсказать местоположение папок, если ему известно имя базы данных. Проблема, с которой я сталкиваюсь, заключается в том, что цикл выполняется только один раз (завершается только первая строка .pgpass).
Это мой скрипт, который будет запущен на исходном сервере:
#!/bin/bash
# Read each line of the input file, parse args separated by semicolon (:)
while IFS=: read host port db user pswd ; do
# Create the dump. No need to enter the password as we're using .pgpass
pg_dump -U $user -h $host -f "$db.sql" $db
# Create a dir in the destination server to copy the files into
ssh user@destination.server mkdir -p webapps/$db/static/media
# Copy the dump to the destination server
rsync -azhr $db.sql user@destination:/home/user
# Copy the website files and folders to the destination server
rsync -azhr --exclude "*.thumbnails*" webapps/$db/static/media/ user@destination.server:/home/user/webapps/$db/static/media
# At this point I expect the script to continue to the next line, but if exits at the first line
done < $1
Это .pgpass, файл для анализа:
localhost:*:db_name1:db_user1:db_pass1
localhost:*:db_name3:db_user2:db_pass2
localhost:*:db_name3:db_user3:db_pass3
# Many more...
И вот как я это называю:
./my_script.sh .pgpass
На данный момент все работает. Создается первый дамп, который передается на сервер назначения вместе со связанными файлами и папками. Проблема в том, что скрипт завершается там и не будет анализировать другие строки .pgpass
. Я закомментировал все строки, связанные с rsync
(поэтому скрипт создает только дампы), и он работает правильно, выполняя один раз для каждой строки в скрипте. Как я могу заставить скрипт не завершать работу после выполнения rsync?
Кстати, я использую ssh-аутентификацию на основе ключа для подключения серверов, поэтому сценарий полностью не требует подсказок.
Ответ №1:
Давайте спросим shellcheck:
$ shellcheck yourscript
In yourscript line 4:
while IFS=: read host port db user pswd ; do
^-- SC2095: ssh may swallow stdin, preventing this loop from working properly.
In yourscript line 8:
ssh user@destination.server mkdir -p webapps/$db/static/media
^-- SC2095: Add < /dev/null to prevent ssh from swallowing stdin.
И вот так.
Комментарии:
1. Отлично! Я просто передал параметр -n в ssh, который выполняет то же самое, и сейчас он работает. Спасибо, что поделились shellcheck.