Bash Script - запуск функций с переменными в цикле - PullRequest
1 голос
/ 11 декабря 2011

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

В своем текущем состоянии скрипт, который у меня есть, вызывает три функции bashи сценарий python (который отправляет электронную почту с помощью stderr и stdout) для каждого общего ресурса, из которых их несколько (4 сейчас, а может и до 6-8), и выглядит это так:

create_log_dir "$share1_backup"
create_log "$share1_backup" "$log_file"
create_rsync_cmd "$log_file"

python backup.py $email_address \
"$rsync_command $rsync_args $share1 $share1_backup"

Таким образом, код выше будет примерно 20-30 строк для всех акций.Я надеялся сделать цикл, который проходит через эти шаги для каждого ресурса, который выглядит примерно так (пример, похожий на псевдокод):

for var in list (each $share_var and $log_var)
do
  create_log_dir "$share_var"
  create_log "$share_var" "$log_var"
  create_rsync_cmd "$log_var"
done

Я попробовал этот формат с некоторыми опциями bash и не смог его получитьработать.Все еще новичок в bash, поэтому я надеюсь получить несколько полезных советов.

Заранее спасибо.

ОБНОВЛЕНИЕ РЕДАКТИРОВАНИЯ

Вот переменные пути и журнала, а также цикл for, который я использую:

#variables
share1="/path/to/share/"
share1_backup="/path/to/share/backup"

# log creation
# If the 'rsync_logs' directory in destination doesn't exist, create it.
create_log_dir()
{
   backup_dest=$1
   if [ ! -d "$backup_dest/rsync_logs" ]
   then
      mkdir $backup_dest/rsync_logs
   fi
}

# Check for log_file existence; append '_alt' if exists.
create_log()
{
   backup_dest=$1
   log_file=$2
   log_file="$backup_dest/rsync_logs/$(date +"%Y-%m%d")_rsync_output.log"
   if [ -f $log_file ]
   then
      log_file="${log_file}_alt"
   fi
}

#loop
for pair in "share1_backup log_file"
do
  set -- $pair
  share=$1
  log=$2

  create_log_dir "$share"
  create_log "$share" "$log"
  create_rsync_cmd "$log"
done

Итак, я попробовал это с исходным ответом:

for pair in "share1_backup log_file"

и... с помощью метода переменных (ни один из них не работал - первый дал ошибку, потому что каталог share1_backup/rsync_logs не существовал - он не использовал переменную):

for pair in "${share1_backup} ${log_file}"

Этот второй результат привел к пустому файлу журнала.

ОБНОВЛЕНИЕ РЕДАКТИРОВАНИЯ 2

Я думаю, что лучший подход к этому, так что оба ответа ниже будут оба работать, чтобы построить журналы в другом месте.Первоначально я думал, что было бы неплохо сохранить их в месте назначения резервной копии, но с другой стороны, было бы целесообразно сохранить журналы на компьютере, на котором смонтированы все общие ресурсы, для согласованности.Затем я могу написать скрипт, который периодически копирует их, если они должны быть на целевых дисках.Таким образом, я могу заранее создать переменную log_file, а затем использовать ее в цикле, как отметил Дэвид К. Хесс.

Еще раз спасибо.

Ответы [ 2 ]

3 голосов
/ 11 декабря 2011

Этот подход должен работать, пока в ваших путях нет пробелов:

for pair in "share1_var log1_var" "share2_var log2_var"
do
    set -- $pair
    share_var = $1
    log_var = $2
    create_log_dir "$share_var"
    create_log "$share_var" "$log_var"
    create_rsync_cmd "$log_var"
done
2 голосов
/ 12 декабря 2011

А как насчет использования массива? Это работает, даже если ваши значения содержат пробелы.

array=("share1" "log1"
       "share2" "log2")
for ((i=0; i<${#array[@]}; i+=2)) ; do
    share_var=${array[i]}
    log_var=${array[i+1]}
    create_log_dir "$share_var"
    create_log "$share_var" "$log_var"
    create_rsync_cmd "$log_var"
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...