bash script + rsync: bash не синхронизируется с хостом? - PullRequest
3 голосов
/ 20 мая 2011

Я только с настоящего утра пишу настоящие .sh сценарии, и я немного застрял. Я пытаюсь написать скрипт, чтобы проверить, запущен ли процесс, и запустить его, если это не так. (Я планирую запускать этот скрипт один раз каждые 10-15 минут с cron.)

Вот что у меня есть:

#!/bin/bash

APPCHK=$(ps aux | grep -c "/usr/bin/rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics  imgserv@192.168.0.140:~/webapps/pavlick_container/public/images
")

RUNSYNC=$(rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics  imgserv@192.168.0.140:~/webapps/pavlick_container/public/images)

if [ $APPCHK < '2' ];
  then
    $RUNSYNC
fi

exit

Вот ошибка, которую я получаю:

$ ./image_sync.sh 
rsync: mkdir "/home/i/webapps/pavlick_container/public/images" failed: No such file or directory (2)
rsync error: error in file IO (code 11) at main.c(595) [Receiver=3.0.7]
rsync: connection unexpectedly closed (9 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(601) [sender=3.0.7]
./image_sync.sh: line 8: 2: No such file or directory

TRTWF это то, что

rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics imgserv@192.168.0.140:~/webapps/pavlick_container/public/images

прекрасно работает из окна терминала.

Что я делаю не так?

Ответы [ 5 ]

5 голосов
/ 21 мая 2011
  • Ваш grep вызов неверен по двум причинам.Шаблон не должен включать новую строку.Чтобы найти точную строку, используйте grep -F 'substring' или grep -xF 'exact whole line'.
  • . Поиск, если процесс выполняется с ps | grep, очень хрупок.В большинстве юнитов (по крайней мере, Solaris, Linux и * BSD) используйте pgrep : pgrep -f 'PATTERN' возвращает true, если есть запущенный процесс, чья командная строка соответствует PATTERN.
    • Каждая программа возвращает код состояния, либо 0 для обозначения успеха, либо число от 1 до 255 для обозначения ошибки.В оболочке любая команда является допустимым логическим выражением;код состояния 0 обрабатывается как истина, а все остальное - как ложь.
  • $(…) означает выполнение команды в круглых скобках и захват ее вывода.Таким образом, rsync выполняется, как только оболочка достигает определения переменной RUNSYNC.Чтобы сохранить блок кода оболочки, используйте функцию (пример ниже, хотя здесь вам на самом деле не нужна функция, вы могли бы просто написать код напрямую).
  • Ваш тест [ $APPCHK < 2 ] должен быть [ $APPCHK -lt 2 ]: < означает перенаправление ввода.(В bash вы также можете написать [[ foo < bar ]], но это сравнение строк, а не числовое сравнение.)
  • ~/ в начале пути удаленного rsync необязательно.Кроме того, -e ssh является значением по умолчанию, если ваша версия rsync действительно старая.
  • exit в конце скрипта бесполезна, скрипт все равно завершится.

Вот сценарий, учитывающий вышесказанное:

#!/bin/bash
 run_rsync () {
     rsync -rvz '/home/e-smith/files/ibays/drive-i/files/Warehouse Pics/organized_pics' \
           imgserv@192.168.0.140:webapps/pavlick_container/public/images
}
process_pattern='/usr/bin/rsync -rvz /home/e-smith/files/ibays/drive-i/files/Warehouse Pics/organized_pics imgserv@192\.168\.0\.140:webapps/pavlick_container/public/images'
if pgrep -xF "$process_pattern"; then
  run_rsync
fi
1 голос
/ 21 мая 2011

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

RUNSYNC="rsync -rvz -e ssh /home/e-smith/files/ibays/drive-i/files/Warehouse\ Pics/organized_pics  imgserv@192.168.0.140:~/webapps/pavlick_container/public/images"
if ! pgrep -f "rsync.*organized_pics"; then $RUNSYNC; fi
1 голос
/ 20 мая 2011

С вашей командой rsync похоже, что какой-то каталог по этому пути неверен: ~ / webapps / pavlick_container / public / images

Вы проверили на сервере 192.168.0.140 в домашнем каталоге imgserv, чтобы увидеть, существует ли pavlick_container / public? Это мое предположение.

0 голосов
/ 20 мая 2011

Если в вашем реальном коде отсутствует закрывающая dlb-кавычка для цели grep, вы получите странные результаты с самого начала.

Кроме того, ps aux не будет отображать полный результат командной строки, как вы показываете (по крайней мере, на всех ps s, которые я использовал).

Вам нужно сделать это ps auxwww.Часто вы увидите, как люди добавляют | grep -v grep | (в какой-то момент вы поймете, почему).Это можно уменьшить, изменив цель статического поиска, например, "/ usr / bin / rsync" на "/ usr / bin / [r] sync".

Другие пользователи также помогают с их комментариями.Использование файла флага, как упоминает @DiegoSevilla, незначительно устарело.используйте mkdir /tmp/MyWatcher_flagDir для вашего флага.Создание каталогов - это элементарное действие (в отличие от создания файлов), и это устранит любые ошибки, с которыми вы можете столкнуться, если две копии монитора будут пытаться создать файл флага одновременно.Только один процесс сможет создать или удалить флаг dir.

Надеюсь, это поможет.

0 голосов
/ 20 мая 2011

Прежде всего, способ проверки, запущена ли программа, в основном неправильный. Это может или не может работать. Вы должны полагаться на какой-то специальный файл, который вы создаете при запуске скрипта, который он удаляет при завершении скрипта. Это сообщит вам, если скрипт запущен, просто проверив, существует ли этот файл.

Затем попробуйте либо поставить \ перед ~, либо полностью удалить ~/. Если cron запускается от имени другого пользователя, тильда будет заменена в клиенте на каталог пользователя. Это работает для командной строки, потому что, возможно, домашний каталог вашего пользователя на обеих машинах совпадает, но не совпадает с пользователем, с которым работает cron. Угадайте на этом этапе, но снова попробуйте удалить ~/ и посмотреть, работает ли он.

...