diff --git a/capture_hourly.sh b/capture_hourly.sh index 38d63b7..4652d42 100755 --- a/capture_hourly.sh +++ b/capture_hourly.sh @@ -6,25 +6,82 @@ SCRIPT_OWNER="${CAPTURE_USER:-$(stat -c %U "$SCRIPT_DIR")}" SCRIPT_OWNER_HOME="$(getent passwd "$SCRIPT_OWNER" | cut -d: -f6)" cd "$SCRIPT_DIR" -source "$SCRIPT_DIR/.env" +ENV_FILE="$SCRIPT_DIR/.env" +declare -A DOTENV_VALUES + +trim_whitespace() { + local value="$1" + value="${value#"${value%%[![:space:]]*}"}" + value="${value%"${value##*[![:space:]]}"}" + printf '%s' "$value" +} + +load_env_file() { + local line key value quote_char + + if [[ ! -f "$ENV_FILE" ]]; then + echo "Не найден .env: $ENV_FILE" >&2 + exit 1 + fi + + while IFS= read -r line || [[ -n "$line" ]]; do + line="${line%$'\r'}" + line="$(trim_whitespace "$line")" + + [[ -z "$line" || "$line" == \#* ]] && continue + + if [[ "$line" == export\ * ]]; then + line="${line#export }" + fi + + [[ "$line" == *=* ]] || continue + + key="$(trim_whitespace "${line%%=*}")" + value="$(trim_whitespace "${line#*=}")" + + if [[ ${#value} -ge 2 ]]; then + quote_char="${value:0:1}" + if [[ ( "$quote_char" == "'" || "$quote_char" == '"' ) && "${value: -1}" == "$quote_char" ]]; then + value="${value:1:${#value}-2}" + fi + fi + + DOTENV_VALUES["$key"]="$value" + done < "$ENV_FILE" +} + +get_env_setting() { + local key="$1" + local default="${2-}" + + if [[ -n "${!key+x}" ]]; then + printf '%s' "${!key}" + elif [[ -n "${DOTENV_VALUES[$key]+x}" ]]; then + printf '%s' "${DOTENV_VALUES[$key]}" + else + printf '%s' "$default" + fi +} + +load_env_file ############################ # НАСТРОЙКИ ############################ -BASE_DIR="${CAPTURE_BASE_DIR:-${SCRIPT_OWNER_HOME}/dataset/noise}" +BASE_DIR="$(get_env_setting CAPTURE_BASE_DIR "${SCRIPT_OWNER_HOME}/dataset/noise")" # Путь к python из venv -PYTHON_BIN="${PYTHON_BIN:-$SCRIPT_DIR/.venv-sdr/bin/python}" +PYTHON_BIN="$(get_env_setting PYTHON_BIN "$SCRIPT_DIR/.venv-sdr/bin/python")" # Путь к headless скрипту -SCRIPT_PATH="${SCRIPT_PATH:-$SCRIPT_DIR/scripts_nn/data_saver_headless.py}" +SCRIPT_PATH="$(get_env_setting SCRIPT_PATH "$SCRIPT_DIR/scripts_nn/data_saver_headless.py")" -RUN_ONCE="${RUN_ONCE:-0}" -CAPTURE_LOG_FILE="${CAPTURE_LOG_FILE:-$BASE_DIR/capture_hourly.log}" +RUN_ONCE="$(get_env_setting RUN_ONCE "0")" +CAPTURE_LOG_FILE="$(get_env_setting CAPTURE_LOG_FILE "$BASE_DIR/capture_hourly.log")" SYSTEMCTL_BIN=(systemctl) CURRENT_CAPTURE_PID="" -CURRENT_SERVICE_UNIT="" +CURRENT_SERVICE_UNITS=() @@ -54,32 +111,32 @@ declare -A SERIAL declare -A FREQ_HZ declare -A SERVICE_UNIT -SERIAL[433]="$hack_433" +SERIAL[433]="$(get_env_setting hack_433)" FREQ_HZ[433]="433000000" -SERIAL[750]="$hack_750" +SERIAL[750]="$(get_env_setting hack_750)" FREQ_HZ[750]="750000000" -SERIAL[915]="$hack_915" +SERIAL[915]="$(get_env_setting hack_915)" FREQ_HZ[915]="915000000" -SERIAL[1200]="$hack_1200" +SERIAL[1200]="$(get_env_setting hack_1200)" FREQ_HZ[1200]="1200000000" -SERIAL[2400]="$hack_2400" +SERIAL[2400]="$(get_env_setting hack_2400)" FREQ_HZ[2400]="2400000000" -SERIAL[3300]="$hack_3300" +SERIAL[3300]="$(get_env_setting hack_3300)" FREQ_HZ[3300]="3300000000" -SERIAL[4500]="$hack_4500" +SERIAL[4500]="$(get_env_setting hack_4500)" FREQ_HZ[4500]="4500000000" -SERIAL[5200]="$hack_5200" +SERIAL[5200]="$(get_env_setting hack_5200)" FREQ_HZ[5200]="5200000000" -SERIAL[5800]="$hack_5800" +SERIAL[5800]="$(get_env_setting hack_5800)" FREQ_HZ[5800]="5800000000" SERVICE_UNIT[433]="dronedetector-sdr-433.service" @@ -109,33 +166,69 @@ service_exists() { systemctl_run show "$unit" >/dev/null 2>&1 } +service_is_active() { + local unit="$1" + systemctl_run is-active --quiet "$unit" +} + +remember_service_unit() { + local unit="$1" + local existing + + for existing in "${CURRENT_SERVICE_UNITS[@]}"; do + if [[ "$existing" == "$unit" ]]; then + return 0 + fi + done + + CURRENT_SERVICE_UNITS+=("$unit") +} + stop_band_service() { local band="$1" - local unit="${SERVICE_UNIT[$band]:-}" + local serial="${SERIAL[$band]:-}" + local other_band unit other_serial - if [[ -z "$unit" ]]; then - log "Для band=$band не найден service unit" + if [[ -z "$serial" ]]; then + log "Для band=$band пустой serial, пропускаю stop/start сервисов" return 0 fi - if ! service_exists "$unit"; then - log "Service unit $unit не установлен, пропускаю stop/start" - return 0 - fi + CURRENT_SERVICE_UNITS=() + for other_band in "${!SERVICE_UNIT[@]}"; do + unit="${SERVICE_UNIT[$other_band]:-}" + other_serial="${SERIAL[$other_band]:-}" - log "Останавливаю service $unit перед записью band=$band" - systemctl_run stop "$unit" - CURRENT_SERVICE_UNIT="$unit" + if [[ -z "$unit" || -z "$other_serial" || "$other_serial" != "$serial" ]]; then + continue + fi + + if ! service_exists "$unit"; then + log "Service unit $unit не установлен, пропускаю" + continue + fi + + if service_is_active "$unit"; then + remember_service_unit "$unit" + fi + + log "Останавливаю service $unit перед записью band=$band" + systemctl_run stop "$unit" + done } start_current_service() { - if [[ -z "$CURRENT_SERVICE_UNIT" ]]; then + local unit + + if [[ "${#CURRENT_SERVICE_UNITS[@]}" -eq 0 ]]; then return 0 fi - log "Запускаю service $CURRENT_SERVICE_UNIT после записи" - systemctl_run start "$CURRENT_SERVICE_UNIT" - CURRENT_SERVICE_UNIT="" + for unit in "${CURRENT_SERVICE_UNITS[@]}"; do + log "Запускаю service $unit после записи" + systemctl_run start "$unit" + done + CURRENT_SERVICE_UNITS=() } cleanup_capture() { @@ -146,10 +239,13 @@ cleanup_capture() { fi CURRENT_CAPTURE_PID="" - if [[ -n "$CURRENT_SERVICE_UNIT" ]]; then - log "Восстанавливаю service $CURRENT_SERVICE_UNIT при завершении скрипта" - systemctl_run start "$CURRENT_SERVICE_UNIT" || true - CURRENT_SERVICE_UNIT="" + if [[ "${#CURRENT_SERVICE_UNITS[@]}" -gt 0 ]]; then + local unit + for unit in "${CURRENT_SERVICE_UNITS[@]}"; do + log "Восстанавливаю service $unit при завершении скрипта" + systemctl_run start "$unit" || true + done + CURRENT_SERVICE_UNITS=() fi } @@ -200,10 +296,13 @@ ensure_requirements() { mkdir -p "$BASE_DIR" mkdir -p "$(dirname "$CAPTURE_LOG_FILE")" - if [[ -n "${CAPTURE_ORDER:-}" ]]; then + local capture_order + capture_order="$(get_env_setting CAPTURE_ORDER)" + + if [[ -n "$capture_order" ]]; then ORDER=() local band - for band in ${CAPTURE_ORDER//,/ }; do + for band in ${capture_order//,/ }; do ORDER+=("$band") done fi