Bark + SDR: Know When Recording Finishes or Fails

This is the seventh article in my Bark series. If you have read the first six, you already have Bark, a relay Worker, and scripts that watch folders and logs. This article is the most practical one for me: I start a long recording, walk away, and I want my phone to tell me three things, and only those three things. First, the recording finished. Second, the disk is running low. Third, the recording I expected never appeared, or came out empty.

You need the relay from Article 2. If that test push has not arrived yet, do that article first, then come back here. Article 4 was one satellite pass. This one is for any long recording, with disk and missing-file checks added.

The script is still short, and it still uses only the standard Python library.

I spent time arranging this one because it is the most pieces at once: recording, disk, missing file, and automatic restart. I wanted you to finish it in one run and trust it afterwards, with a result you are happy with. If it feels complex, go back to Article 3 first. That satellite pass reminder is the easiest way in, and once that push arrives on your phone, the rest of the series makes more sense.

And one thing to be clear about: I ran this once, it worked, and then I shared it. I have not tested it over a long period, across reboots and long recordings. If a check behaves differently on your computer, treat your own system as the reference, not my example numbers.

Before you start: tools, and how to check each one

Do not start the steps until every check below passes.

  1. Bark and a working relay Worker, from the first three articles. Check: send yourself a test push, as in Article 2. You will test the relay again with the script test in Step 3 below.
  2. Your relay Worker address and shared passphrase, written on paper. Check: you can read both back without opening Cloudflare.
  3. A computer that records, sleep mode disabled. Check: the computer does not enter sleep mode for an hour with the recording program open.
  4. Python on that computer. Check: python --version on Windows, or python3 --version on Mac and Linux, returns a version number.
  5. Your recording program, already working by hand. Check: record ten seconds by hand and find the file, its folder, and its file ending.
  6. Two numbers, written on paper, before you run anything. First, your low-disk limit in gigabytes, for example 5. Second, how long you will wait before calling a recording missing, for example 10 minutes after its expected start. Do not leave these numbers to guesswork while the script runs.

Recording programs and schedulers differ from system to system. Windows uses Task Scheduler, Mac and Linux use cron, and the menu words differ again. The idea is the same in all of them: start this script when you log on or boot, and let it write its log without you. Follow the version for your own system below, and check the log after a reboot, as Step 4 says.

If you do not know how to open a terminal yet, jump to the skills section below, then come back here. The checklist above will still be here.

Code repository

The full script is pasted in this article, below. The same file also lives in my public code repository, in the folder sdr-scripts/, as 04-recording-status.py. Open that folder, open the file, press Raw, select all, and copy. Change only the lines marked CONFIG. The script contains only placeholders. Do not put your Bark key in it. Your Bark key stays inside the relay Worker.

Before you start, three things to know

Terminal, saving a .py file, and copying from Raw: I wrote those out in Article 4, and I am not going to copy them here again. If you have not done them yet, do them there first, then come back. Two reminders for this article only: save as .py, not .py.txt, and write folder paths with forward slashes. The scheduler part is in Step 4 below, with its own log file.

Step 1: Write down what “finished” and “failed” mean for you

Before any code, write three lines on paper. First, the recording folder and file ending. Second, the expected file name pattern, if your program names files by time or by frequency, or write “any new file” if it does not. Third, your low-disk limit and your missing-file wait time, from the tool checks above.

Check point: you can read those three lines back, and another person could use them to find the same folder and the same file. If you cannot, the script will also not know what to watch.

Your recording program may name its folder and format settings differently. What counts is the folder you actually record into, the file ending you actually get, and the two numbers you wrote down.

Step 2: Copy the script

Save the code below as recording-status.py. Change only the CONFIG lines. The script does three checks, in a loop, every 60 seconds. First, it watches for a new file whose size stays stable for 60 seconds, and pushes “Recording finished”. Second, it checks free disk space, and pushes “Disk low” once, until space recovers. Third, it watches for an expected file: if you set an expected file name and that file has not appeared 10 minutes after the script starts, it pushes “Recording missing”. If you leave the expected file name empty, that third check stays off, which is the right choice for an unscheduled recording.

import json
import os
import shutil
import sys
import time
import urllib.request

# CONFIG: change these lines only.
RELAY_URL = "https://YOUR-WORKER.workers.dev/push"
RELAY_SECRET = "YOUR-PASSPHRASE"
WATCH_FOLDER = "C:/Recordings"
FILE_ENDING = ".wav"
LOW_DISK_GB = 5
EXPECTED_FILE = ""
MISSING_MINUTES = 10
STABLE_SECONDS = 60

# Pushes are title-only: on my phone, a push with a body is not
# spoken aloud, so everything goes into the title and there is no body.
def send_push(title):
    data = json.dumps({"title": title, "group": "sdr-status"}).encode()
    req = urllib.request.Request(RELAY_URL, data=data, method="POST")
    req.add_header("Content-Type", "application/json")
    req.add_header("X-Relay-Secret", RELAY_SECRET)
    with urllib.request.urlopen(req, timeout=20) as resp:
        print(resp.read().decode())

def main():
    if len(sys.argv) > 1 and sys.argv[1] == "test":
        send_push("Test push, relay path works")
        return
    seen = {}
    disk_warned = False
    missing_warned = False
    start = time.time()
    while True:
        for name in os.listdir(WATCH_FOLDER):
            if not name.lower().endswith(FILE_ENDING):
                continue
            path = os.path.join(WATCH_FOLDER, name)
            size = os.path.getsize(path)
            if size == 0:
                continue
            if name not in seen:
                seen[name] = (size, time.time())
            elif seen[name][0] == size and time.time() - seen[name][1] >= STABLE_SECONDS:
                free_gb = shutil.disk_usage(WATCH_FOLDER).free / 1024 / 1024 / 1024
                send_push("Recording finished, %s, %.1f MB, %.1f GB free" % (name, size / 1024 / 1024, free_gb))
                del seen[name]
            else:
                seen[name] = (size, time.time())
        free_gb = shutil.disk_usage(WATCH_FOLDER).free / 1024 / 1024 / 1024
        if free_gb < LOW_DISK_GB and not disk_warned:
            send_push("Disk low, %.1f GB free in %s" % (free_gb, WATCH_FOLDER))
            disk_warned = True
        elif free_gb >= LOW_DISK_GB:
            disk_warned = False
        if EXPECTED_FILE and not missing_warned and EXPECTED_FILE not in os.listdir(WATCH_FOLDER):
            if time.time() - start >= MISSING_MINUTES * 60:
                send_push("Recording missing, %s not found after %d minutes" % (EXPECTED_FILE, MISSING_MINUTES))
                missing_warned = True
        time.sleep(60)

if __name__ == "__main__":
    main()

Check point: the CONFIG lines show your own relay address, your own passphrase, your real folder, and your two numbers from Step 1. The relay address must end with /push, with no slash after it. For the folder path, use forward slashes even on Windows, for example C:/Recordings, not backslashes. I skip zero-size files. They are not finished recordings, they are failed or still-starting ones. One more warning: the missing-file timer starts when the script starts, not when the recording is scheduled. Do not start the script with an expected file name hours before that recording is due, or the missing push will fire early. Start it close to the expected time, or leave the expected file name empty until then.

Step 3: Test the push, then test with a short recording

Run python recording-status.py test, or python3 recording-status.py test. On Windows, if typing python opens a store page instead of running anything, use py recording-status.py test instead. Your phone should receive a test push within seconds. Then run the script without the word test, and record ten seconds by hand. The script checks every 60 seconds, and waits 60 seconds of stable size, so allow up to three minutes after the recording stops growing before you conclude it failed. Then the script should push one title, “Recording finished” plus the file name, its size, and free disk space, and no body. The script runs in the foreground until you set up the scheduler in Step 4, so leave that terminal window open for this test.

Check point: a ten-second recording gives one finished push, not a disk push and not a missing push. If a disk push arrives during this test, your low-disk limit is higher than your real free space, or you are watching the wrong disk. Check the free space number in the push title against your computer.

Worked example: an evening recording, from 20:00 to 22:00, step by step

Read this example first, then do the run yourself with your own values, then do Step 4 below for automatic restart. The example values are filled in, so you can see exactly what each line should look like.

This is a concrete example, not a placeholder. The times below are example times only. Replace them with your own recording times afterwards. The steps stay identical.

Example scenario: I record a two-hour evening session. The program is expected to save a file named evening-net.wav, in C:/Recordings, ending in .wav. I want a push if that file never appears, a push if the disk runs low, and a push when the recording finishes.

Step 1, fill the CONFIG lines like this, line by line. Only the first two lines are yours. The other lines are the example.

RELAY_URL = "https://YOUR-WORKER.workers.dev/push"
RELAY_SECRET = "YOUR-PASSPHRASE"
WATCH_FOLDER = "C:/Recordings"
FILE_ENDING = ".wav"
LOW_DISK_GB = 5
EXPECTED_FILE = "evening-net.wav"
MISSING_MINUTES = 20
STABLE_SECONDS = 60

Step 2, follow this timeline, step by step. Start the script at 19:50, close to the expected time, not hours early. The missing timer starts when the script starts, so with 20 minutes set here, a missing push would fire at 20:10 if the file has not appeared by then. That gives ten minutes of grace after the 20:00 recording start, so a slow program start does not trigger a false missing push. At 20:00, start the recording in your program, so the file evening-net.wav appears in the folder. If it still has not appeared by 20:10, your phone should receive a push that would read, in this example:

Recording missing, evening-net.wav not found after 20 minutes

Step 3, while the recording runs from 20:00 to 22:00, the file size grows. If free space falls below 5 GB at any point, your phone should receive a push that would read, in this example, with your real free space number in place of the example number:

Disk low, 4.2 GB free in C:/Recordings

Step 4, at 22:00, stop the recording. The file size stops growing. Allow up to three minutes in total, because this script checks every 60 seconds and waits 60 seconds of stable size. Then your phone should receive a push that would read, in this example, with your real size and free space in place of the example numbers:

Recording finished, evening-net.wav, 320.5 MB, 118.7 GB free

Step 5, for your own recording, change only four things: the folder if yours differs, the expected file name, the low-disk limit if 5 GB does not fit your disk, and the missing minutes if 20 minutes does not fit your schedule. The relay lines and the file ending stay the same, unless your program saves a different ending.

Step 4: Leave it running, and set it to start again after a reboot

Leave the computer, the recording program, and the script all running for a long recording. After the recording, check that you have a finished push with the same file name as the file on disk. Then set the script to start again after a reboot. I give you both systems below, in full. Pick only the one for your computer.

On Windows, use Task Scheduler, with a small start file. First, in the same folder as the script, save a file named run-status.bat, with these two lines, using your real folder path with forward slashes:

cd /d C:/Recordings
python C:/Recordings/recording-status.py >> C:/Recordings/script.log 2>&1

Replace C:/Recordings with your real script folder, in both lines. Save the file as run-status.bat, not run-status.bat.txt. Turn on file name extensions first, as in the skills section, and check the saved name. Then open Task Scheduler, choose Create Basic Task, name it SDR status, set the trigger to When I log on, set the action to Start a program, and choose your run-status.bat file. Finish the task, then log out and log in again.

On Mac and Linux, use cron. First, open a terminal and run which python3. Write down the path it prints, for example /usr/bin/python3. Then run crontab -e. If it asks for an editor, choose nano. If you land in vim instead of nano, press Esc, type :wq, and press Enter. Add this one line at the end, using your real Python path and your real script folder:

@reboot /usr/bin/python3 /home/YOUR-NAME/recording-status.py >> /home/YOUR-NAME/script.log 2>&1

Replace the Python path and the folder with your real ones. Save with Ctrl and O, then Enter, then Ctrl and X to leave nano. Then reboot the computer.

Check point: after a reboot, open script.log in the script folder. It must grow again, without you starting the script by hand. If the log does not grow, the scheduler entry is wrong, and a power cut or a reboot will silently stop all pushes. A script that only runs when you remember to start it is not a status monitor. Articles 4, 5, and 6 use this same Step 4 when you want them to restart automatically.

When it does not push

Fix one thing at a time, then try again.

  1. Did the test push arrive? If not, the relay address or passphrase is wrong, or the computer has no internet. Fix that first.
  2. Is the script still running in an open terminal, or did the scheduler restart it after a reboot? If neither, start it again and fix Step 4.
  3. Is the folder in CONFIG the real folder, with forward slashes? Open that folder and look for a real file.
  4. Did you wait long enough? This script checks every 60 seconds and waits 60 seconds of stable size, so allow up to three minutes after the recording stops growing.
  5. Did a missing push fire early? That means you started the script with an expected file name hours before that recording was due. The missing timer starts when the script starts. Start it close to the expected time instead.

If a step still fails after the checks above, copy this whole article into an AI tool and let it read the article first. Then tell it your recording program, your real folder and file ending, your disk limit, your expected file and missing minutes, and whether you use Task Scheduler or cron, plus the error you saw. Ask it to check your local variables against the article, and to adjust for your system. Do not paste your relay passphrase or your Bark key into any AI tool. Copy the article as published, with placeholders, not your filled-in script.

Appendix: three things that really stop people

  1. Calling a recording missing too early. A recording that has not started yet is not a failed recording. Wait for your missing-file time to pass, and use the expected-file check only for scheduled recordings with a known file name. For unscheduled recording, leave that check off.
  2. Mixing gigabytes and bytes. The low-disk limit in this script is in gigabytes, and the script converts disk space to gigabytes before comparing. If you write 500 thinking it means megabytes, the script will warn only when the disk is nearly empty in the other direction. Write the limit in gigabytes, on paper, before you run it.
  3. The script does not restart after a reboot. This is the most common silent failure. A long recording that spans a reboot, a power cut, or an update will have no pushes unless the scheduler restarts the script. Step 4 exists for this reason: prove a restart, do not assume it.

More in this series: iPhone Low-Power Instant Ham Radio Reminders; One App, Two Websites: Instant Ham Radio Reminders; Satellite Pass Reminders by Hand: Start at 30 Degrees; Bark + SDR: Never Miss a Satellite Recording Again; Bark + SDR: Get Pushed Only When the Repeater Talks; Bark + SDR: A Push When the Band Opens to You.

这是我的 Bark 系列第 7 篇。如果你已经读过前六篇,你已经有 Bark、转发器,和能看文件夹、看日志的脚本。这篇对我来说最实用:我开一次长录音,人走开,只想让手机告诉我三件事,而且只告诉这三件事。第一,录音完成了。第二,磁盘快满了。第三,我等的那次录音一直没出现,或者录出来是空的。

你只需要第 2 篇里的转发器。测试推送还没到,就先去做那篇,再回来。第 4 篇是一次卫星过顶,这篇是任何长录音,加了磁盘和缺文件检查。

第 4 篇讲的是一次卫星过顶、一次录音。这篇讲的是一般的状态:任何一次长录音、任何频率,再加上磁盘检查和缺文件检查。脚本还是很短,而且只用 Python 自带的功能。

这篇我花了点时间整理,因为它一次要管的东西最多:录音、磁盘、缺失、自动重启。我就是想让你一遍做完,之后能放心交给它,拿到自己满意的结果。如果觉得复杂,先回第 3 篇,卫星过顶提醒是最简单的入口,手机上收到一次推送,整个系列后面的做法就好理解了。

还有一点要说清楚:这篇我也是跑了一遍,跑通了,才分享出来,没有经过长时间测试,也没有跨过很多次重启和长录音去验证。如果哪项检查在你的电脑上表现不一样,以你自己的系统为准,不要死守我的实例数字。

开始前:工具准备,和每一件工具的检查

下面每一项检查都通过了,再开始后面的步骤。

  1. 前三篇里的 Bark 和能用的转发器。检查:给自己发一条测试推送。
  2. 转发器地址和共享口令,写在纸上。检查:不用打开 Cloudflare,你就能把这两样读出来。
  3. 一台录音的电脑,禁用休眠功能。检查:录音程序持续运行一小时,电脑保持唤醒状态。
  4. 同一台电脑上的 Python。检查:Windows 运行 python --version,Mac 和 Linux 运行 python3 --version,有版本号回来。
  5. 你的录音程序,已经能手动录制。检查:手动录制十秒,找到文件、文件夹和后缀。
  6. 两个数字,运行任何程序之前先写在纸上。第一,磁盘告警线,单位是 GB,比如 5。第二,等多久才算录音缺失,比如预计开始后 10 分钟。不要等到脚本开始运行后再临时确定这两个数。

录音程序和定时工具在不同系统上都不一样,Windows 用任务计划,Mac 和 Linux 用 cron,菜单文字也不一样。意思还是同一件:登录或者开机时启动这个脚本,让它自己写日志,不用你动手。按下面你那台系统的一节做,第 4 步说的重启后查日志不能省。

如果还不知道怎么打开终端,先跳到下面技能那节,做完再回来,上面的清单还在。

代码仓库

完整脚本贴在这篇文章下面。同一份文件也放在我的公开代码仓库里,文件夹是 sdr-scripts/,文件名是 04-recording-status.py。打开文件夹,打开文件,按 Raw,全选,复制。只改标着 CONFIG 的那几行。脚本里只有占位符,不要把你的 Bark 密钥写进去。你的 Bark 密钥只留在转发器后台。

开始前先会这三样

终端、存 .py 文件、从 Raw 复制,这三样我在第 4 篇里写过了,这里不再抄一遍。还没做过的,先去第 4 篇做完,再回来。这篇只提醒两句:存成 .py,不是 .py.txt;文件夹路径用正斜杠。定时那部分在下面第 4 步,有自己的日志文件。

第 1 步:先写下来,对你来说“完成”和“失败”是什么意思

写任何代码之前,先在纸上写三行。第一,录音文件夹和后缀。第二,如果程序按时间或者频率命名文件,写下预计的文件名规律;如果不是,就写“任何新文件”。第三,你的磁盘告警线和缺文件等待时间,就是上面工具检查里那两个数。

核对点:你能把这三行读出来,而且另一个人拿着这三行也能找到同一个文件夹、同一个文件。读不出来,脚本也不知道该看什么。

你的录音程序里文件夹和格式的设置名字可能不同,算数的是你实际录进的文件夹、实际得到的文件后缀,和你写下来的两个数字。

第 2 步:复制脚本

把下面的代码存成 recording-status.py。只改 CONFIG 那几行。脚本每 60 秒做三项检查。第一,看有没有新文件大小 60 秒不再变,发送一条推送 “Recording finished”。第二,看剩余磁盘空间,低于告警线就发送一次推送 “Disk low”,空间恢复之前不再重复推。第三,看预计文件:如果设了预计文件名,脚本启动 10 分钟后那个文件还没出现,就发送一条推送 “Recording missing”。预计文件名留空,这第三项检查就是关着的,没排程的录音就该这样。

代码见上面英文部分的同一段,配置说明相同。

核对点:CONFIG 那几行是你自己的转发器地址、你自己的口令、你真实的文件夹,和第 1 步里那两个数。转发器地址必须以 /push 结尾,后面不要再加斜杠。文件夹路径哪怕在 Windows 上也要用正斜杠写,比如 C:/Recordings,不要用反斜杠。大小为零的文件我直接跳过。它不是完成的录音,而是失败或者还没开始的录音。再提醒一句:缺文件计时是从脚本启动那一刻开始算的,不是从录音排程那一刻算的。不要提前几个小时就带着预计文件名启动脚本,不然缺失推送会提前误发。临近预计时间再启动,或者之前先把预计文件名留空。

第 3 步:先测推送,再用一次短录音测

运行 python recording-status.py test,Mac 和 Linux 用 python3 recording-status.py test。Windows 上如果输入 python 后打开的是应用商店页面而非执行程序,就改用 py recording-status.py test。几秒内手机应该收到测试推送。然后不带 test 启动脚本,手动录制十秒。脚本每 60 秒检查一次,又要等 60 秒大小不变,所以录音停止变大之后,最多等三分钟再下结论说它失败了。之后它就应该发送一条只有标题的推送:“Recording finished”加上文件名、大小和剩余磁盘空间,没有正文。这次测试时脚本仍在前台运行,终端窗口须保持开启,直到第 4 步设好定时为止。

核对点:一次十秒录音只给一条完成推送,不给磁盘推送、不给缺失推送。测试时来了磁盘推送,说明你的告警线高于真实剩余空间,或者你看错了磁盘。对照推送标题里的剩余空间数和电脑上的实际数。

具体实例:一次晚间录音,20:00 到 22:00,一步一步

先读这个实例,再用你自己的值自己跑一遍,然后按下面第 4 步设自动重启。实例里的值都已填好,你能看到每一行该长什么样。

这是一个具体实例,不是占位符。下面这些时间只是示例时间,之后换成你自己的录音时间。步骤完全一样。

实例情景:我录一次两小时的晚间内容。程序预计存一个叫 evening-net.wav 的文件,在 C:/Recordings 里,后缀是 .wav。我想在文件一直没出现时发送一次推送,磁盘快满时发送一次推送,录完时发送一次推送。

第 1 步,一行一行填 CONFIG。只有前两行是你自己的,其他行是这个实例:

RELAY_URL = "https://YOUR-WORKER.workers.dev/push"
RELAY_SECRET = "YOUR-PASSPHRASE"
WATCH_FOLDER = "C:/Recordings"
FILE_ENDING = ".wav"
LOW_DISK_GB = 5
EXPECTED_FILE = "evening-net.wav"
MISSING_MINUTES = 20
STABLE_SECONDS = 60

第 2 步,按下面这个时间线一步一步走。19:50 启动脚本,临近预计时间,不要提前几小时启动。缺文件计时是从脚本启动算起的,所以这里设 20 分钟,文件到 20:10 还没出现才会推缺失。这样 20:00 开始录音之后还有十分钟宽限,程序启动慢一点也不会误推缺失。20:00 在程序里开始录音,文件夹里出现 evening-net.wav。如果到 20:10 还没出现,你的手机应该收到一条推送,这个实例里会是这样:

Recording missing, evening-net.wav not found after 20 minutes

第 3 步,20:00 到 22:00 录音进行时,文件在变大。任何时候剩余空间掉到 5 GB 以下,你的手机应该收到一条推送,这个实例里会是这样,真实数字换成你自己的剩余空间:

Disk low, 4.2 GB free in C:/Recordings

第 4 步,22:00 停止录音。文件不再变大。总共最多等三分钟,因为这个脚本每 60 秒检查一次,又要等 60 秒大小不变。然后你的手机应该收到一条推送,这个实例里会是这样,真实大小和剩余空间换成你自己的数字:

Recording finished, evening-net.wav, 320.5 MB, 118.7 GB free

第 5 步,换成你自己的录音,只改四处:文件夹如果不一样就改文件夹,预计文件名,磁盘告警线如果 5 GB 不适合你的磁盘就改,缺失分钟数如果 20 分钟不适合你的排程就改。转发器那两行和后缀都不用动,除非你的程序存的是别的后缀。

第 4 步:让它持续运行,并且设好重启后自动运行

电脑、录音程序、脚本均保持运行,以完成一次长录音。录完之后确认:你收到一条完成推送,文件名和磁盘上的文件对得上。然后设好重启后自动运行。下面两种系统我都写全,只做你那台电脑的那一种。

Windows 用任务计划,加一个小启动文件。先在脚本所在文件夹里存一个叫 run-status.bat 的文件,里面就两行,文件夹路径换成你真实的路径,用正斜杠:

cd /d C:/Recordings
python C:/Recordings/recording-status.py >> C:/Recordings/script.log 2>&1

两行里的 C:/Recordings 都换成你真实的脚本文件夹。存成 run-status.bat,不是 run-status.bat.txt。先按技能那节打开文件扩展名显示,确认存下来的名字无误。然后打开任务计划,选创建基本任务,名字叫 SDR status,触发器选登录时,操作选启动程序,选你刚存的 run-status.bat 文件。完成任务后,注销再重新登录一次。

Mac 和 Linux 用 cron。先打开终端,运行 which python3,把打印出来的路径记下来,比如 /usr/bin/python3。然后运行 crontab -e。如果它问用什么编辑器,选 nano。如果打开的是 vim 而不是 nano,按 Esc,输入 :wq,按回车。在最后加这么一行,Python 路径和脚本文件夹都换成你真实的:

@reboot /usr/bin/python3 /home/YOUR-NAME/recording-status.py >> /home/YOUR-NAME/script.log 2>&1

保存按 Ctrl 和 O,再按回车,再按 Ctrl 和 X 退出 nano。然后重启电脑。

核对点:重启之后,打开脚本文件夹里的 script.log,它必须自己又开始变大了,不用你手动启动脚本。日志不动,说明定时项写错了,断电或者重启之后推送将静默停止。仅在手动启动时才运行的脚本,不能算作状态监控。第 4、5、6 篇想自动重启时,也用这一步。

运行失败时,先这样排查

一次只改一处,改完再测一次。

  1. 测试推送到了吗?没到,就是转发器地址或者口令错了,或者电脑没联网。先修这个。
  2. 脚本是否仍在保持开启的终端中运行?或者重启后定时任务启动它了吗?两个都没有,就重新启动它,再修第 4 步。
  3. CONFIG 里写的文件夹是真实文件夹吗?路径用正斜杠了吗?打开那个文件夹看看有没有真实文件。
  4. 等够时间了吗?这个脚本每 60 秒检查一次,又要等 60 秒大小不变,所以录音停止变大之后,最多等三分钟再下结论。
  5. 缺失推送提前来了吗?那就是你提前几个小时就带着预计文件名启动了脚本。缺文件计时是从脚本启动算起的。临近预计时间再启动。

如果按上面的顺序查了还是不行,把整篇文章复制给 AI 工具,先让它读完文章。再告诉它你的录音程序、你真实的文件夹和文件后缀、你的磁盘告警线、预计文件名和缺失分钟数、你用的是任务计划还是 cron、你看到的报错,让它对照文章检查你的本地变量对不对,按你的系统做相应的调整。不要把转发器口令和 Bark 密钥粘给任何 AI 工具,复制的是发表出来的文章(带占位符的那版),不是你填好值的那份脚本。

附录:真正会卡住人的三条

  1. 太早判定录音缺失。还没开始的录音不是失败的录音。等够你定的缺文件时间再下结论,而且预计文件检查只用于有排程、有已知文件名的录音。没排程的录音就把这项关掉。
  2. GB 和字节混了。这篇脚本里的磁盘告警线单位是 GB,脚本先把磁盘空间换算成 GB 再比较。你要是写 500 以为是 MB,告警逻辑就全反了。运行之前先把告警线以 GB 为单位写在纸上。
  3. 重启后脚本不会自动运行。这是最常见的静默失效。一次长录音跨过重启、断电或者更新,定时任务未启动脚本,推送就全没了。第 4 步就是为这个设的:证明一次重启,不靠假设。

这个系列里还有:第 1 篇:为什么用 Bark 做提醒、第 2 篇:一个 App、两个网站、第 3 篇:卫星过顶提醒、第 4 篇:卫星录音、第 5 篇:中继守听、第 6 篇:波段打开。