Управление заданиями: Как сохранить вывод фонового задания в переменной

Вопрос или проблема

Использование Bash в OSX.

В моем скрипте есть эти 2 строки:

nfiles=$(rsync -auvh --stats --delete --progress --log-file="$SourceRoot/""CopyLog1.txt" "$SourceTx" "$Dest1Tx" | tee /dev/stderr | awk '/files transferred/{print $NF}') &
nfiles2=$(rsync -auvh --stats --delete --progress --log-file="$SourceRoot/""CopyLog2.txt" "$SourceTx" "$Dest2Tx" | tee /dev/stderr | awk '/files transferred/{print $NF}')

Когда я использую & после первой строки (чтобы выполнить две команды rsync параллельно), мой последующий вызов $nfiles ничего не возвращает.

Код:

osascript -e 'display notification "'$nfiles' файлов перенесено в MASTER," & return & "'$nfiles2' перенесено в BACKUP," & return & "Созданы файлы журнала" with title "Копирование завершено"'

Не могу понять, что происходит. Мне нужно, чтобы 2 rsync выполнялись одновременно.

Причина, по которой ваш пример не будет работать, заключается в том, что фоновая команда выполняется в окружении подпроцесса, поэтому значение $nfiles не будет доступно (т.е. в вашем примере оно потеряно).

Одним из простых способов решить эту проблему было бы использовать временный файл. В обобщенном примере кода ниже я заменил ваши конвейеры rsync на более простые команды, которые sleep и выводят произвольное число:

tmpfile=$(mktemp) || exit

# убедитесь, что временный файл будет удален при прерывании или ошибке:
trap 'rm -f "$tmpfile"; exit 1' HUP INT QUIT TERM

# запустите первую команду в фоновом режиме и сохраните вывод во временный файл:
(sleep 3; echo 1) >"$tmpfile" &

nfiles2=$(sleep 1; echo 2)

# дождитесь завершения фоновой команды:
wait

# сохраните данные временного файла в переменные:
nfiles=$(cat "$tmpfile")

# удалите временные файлы при нормальном завершении:
rm -f "$tmpfile"

# $nfiles и $nfiles2 теперь должны содержать нужные данные
printf 'nfiles=%s\n' "$nfiles"
printf 'nfiles2=%s\n' "$nfiles2"

Ответ или решение

Ваша проблема связана с тем, что вы запускаете первую команду в фоновом режиме, и переменная $nfiles не сохраняет значение, так как оно теряется в дочернем процессе. Чтобы сохранить вывод фоновой задачи в переменной, можно использовать временный файл. Вот как можно модифицировать ваш скрипт:

# Создайте временный файл для хранения вывода первой команды
tmpfile=$(mktemp) || exit 1

# Обеспечьте удаление временного файла при аварийном завершении
trap 'rm -f "$tmpfile"; exit 1' HUP INT QUIT TERM

# Запустите первую команду в фоновом режиме и записывайте вывод в временный файл
(rsync -auvh --stats --delete --progress --log-file="$SourceRoot/CopyLog1.txt" "$SourceTx" "$Dest1Tx" | tee /dev/stderr | awk '/files transferred/{print $NF}') > "$tmpfile" &

# Выполните вторую команду и сохраняйте ее вывод в переменной
nfiles2=$(rsync -auvh --stats --delete --progress --log-file="$SourceRoot/CopyLog2.txt" "$SourceTx" "$Dest2Tx" | tee /dev/stderr | awk '/files transferred/{print $NF}')

# Дождитесь завершения фоновой задачи
wait

# Сохраните данные из временного файла в переменную
nfiles=$(cat "$tmpfile")

# Удалите временные файлы
rm -f "$tmpfile"

# Теперь переменные $nfiles и $nfiles2 содержат желаемые данные
osascript -e 'display notification "'"$nfiles"'" files transferred to MASTER," & return & "'"$nfiles2"'" transferred to BACKUP," & return & "Log Files Created" with title "Copy Complete"'

Пояснения:

  1. Создание временного файла: Использовался mktemp, чтобы создать временный файл для хранения вывода первой команды.
  2. Фоновый процесс: Первая команда rsync теперь записывает свой вывод в временный файл, что позволяет нам получить значение позже.
  3. wait: После запуска фоновой команды мы вызываем wait, чтобы дождаться завершения фонового процесса перед тем, как запрашивать данные из временного файла.
  4. Удаление временного файла: Убедитесь, что временный файл удаляется как в случае успешного завершения, так и при возникновении ошибок.

Теперь переменные $nfiles и $nfiles2 содержат количество переданных файлов, и вы можете использовать их в вашем уведомлении.

Оцените материал
Добавить комментарий

Капча загружается...