bash - возвращает статус из функции в фоновом режиме
У меня есть скрипт bash примерно следующей структуры:
function download {
# download a big file
}
function prepare_stuff {
# prepare some stuff
}
function process_download {
# process the downloaded file
}
download & prepare_stuff & wait
process_download
Первое, что он делает, это загружает файл размером в несколько сотен мегабайт. Пока идет загрузка, некоторые другие вещи готовятся в фоновом режиме. Когда оба они завершены, загрузка обрабатывается.
download
может закончиться тремя разными способами:
- Ошибка загрузки (например, сервер недоступен)
- Файл был успешно загружен
- Файл не изменился на сервере с момента последней загрузки
Случай 1 является ошибочным условием (в этом случае функция должна возвращать что-то отличное от нуля), а 2 и 3 - нет (т.е. возвращаемое значение должно быть нулевым).
Теперь я хочу process_download
чтобы пропустить фактическую обработку, когда встречается случай 1 или 3, поэтому мне нужно передать какой-то статус обратно download
, поскольку download
работает в подоболочке, переменная не будет работать (присваивания происходят в подоболочке и не передаются в родительскую оболочку).
Как я могу передать какое-то значение из функции в подоболочке обратно в родительскую оболочку?
2 ответа
Я закончил тем, что сделал что-то похожее на то, что предложил Фред.
Прежде всего, я отказался от идеи "файл не изменен на сервере = нет ошибки" и теперь использую код возврата, чтобы просто указать, есть ли у нас загрузка для обработки - 0, если был загружен новый файл, 1, если загрузка не удалась или не было никаких изменений. С этим гораздо проще справиться.
Затем:
function download {
# download a big file
# return nonzero if download failed
# else return nonzero if file has not changed
# else return 0 (download successful, file has changed)
}
function prepare_stuff {
# prepare some stuff
}
function process_download {
# process the downloaded file
}
download &
PID_DOWNLOAD=$!
prepare_stuff &
PID_PREPARE_STUFF=$!
wait $PID_PREPARE_STUFF
wait $PID_DOWNLOAD && process_download || echo "Nothing to process."
Вы можете сделать это:
download &
download_pid=$!
prepare_stuff &
prepare_pid=$!
result=0
wait $download_pid || result=$?
wait $prepare_pid
Затем, result
будет содержать код возврата вашей предыдущей команды загрузки, и оба фоновых задания будут завершены, и вы можете сделать что-то вроде:
[[ $result = 0 ]] || process_download
С разъяснениями относительно вашего третьего состояния я мог бы сделать ответ более полным.