如何通过Shell脚本准确判断Google Chrome所有下载任务完成?
如何准确判断Google Chrome所有下载任务已完成?
我每天需要通过Chrome插件批量下载大量图片,需要编写脚本判断所有下载完成,以便触发后续处理。尝试过两种方法但都有问题:
方法1:lsof命令方案(不稳定)
用以下命令检测Chrome是否在访问下载目录:
lsof -c /Chrome/i | grep "/Users/ifxl/Downloads/tmp_images/ref" lsof -c /Chrome/i | grep "/Users/ifxl/Downloads/"
但该方法经常提前判定下载完成,实际仍在下载中,稳定性差。
方法2:stat脚本方案(报错)
编写了监控目录修改时间的Shell脚本,但执行报错:
#! /bin/bash export LANG="en_US.UTF-8" PATH=/usr/local/bin:$PATH dir="/Users/ifxl/Downloads/tmp_images/ref/" # check whether $dir exists #test -d "${dir}" || exit 1 last=0 current=1 while [ "$last" != "$current" ]; do last=$current current=$(find "${dir}" -exec stat -c "%Y" \{\} \; | sort -n | tail -1) sleep 10 done echo "directory is now stable..."
错误提示:
stat: illegal option -- c usage: stat [-FLnq] [-f format | -l | -r | -s | -x] [-t timefmt] [file ...]
原因是macOS的stat命令参数与Linux不同,-c是Linux参数,macOS需要用-f指定格式。
推荐的优雅准确方案
方案1:用AppleScript直接查询Chrome下载状态(最可靠)
macOS上可以通过AppleScript直接获取Chrome的下载任务状态,这是最准确的方式,因为直接读取Chrome的内部状态:
tell application "Google Chrome" set allDownloads to downloads set isDownloading to false repeat with dl in allDownloads if state of dl is downloading then set isDownloading to true exit repeat end if end repeat return not isDownloading end tell
可以把这个AppleScript嵌入到Shell脚本中,循环检测直到返回true:
#!/bin/bash while true; do # 执行AppleScript并获取结果 downloadComplete=$(osascript -e 'tell application "Google Chrome" set allDownloads to downloads set isDownloading to false repeat with dl in allDownloads if state of dl is downloading then set isDownloading to true exit repeat end if end repeat return not isDownloading end tell') if [ "$downloadComplete" = "true" ]; then echo "所有Chrome下载任务已完成" break fi sleep 5 done # 这里添加后续处理流程
方案2:修复macOS适配的stat监控脚本
如果不想用AppleScript,可以修改原脚本,适配macOS的stat命令:
#!/bin/bash export LANG="en_US.UTF-8" PATH=/usr/local/bin:$PATH dir="/Users/ifxl/Downloads/tmp_images/ref/" test -d "${dir}" || exit 1 last=0 current=1 while [ "$last" != "$current" ]; do last=$current # macOS stat用-f "%m"获取文件修改时间(Unix时间戳) current=$(find "${dir}" -type f -exec stat -f "%m" {} \; | sort -n | tail -1) # 处理目录为空的情况 if [ -z "$current" ]; then current=0 fi sleep 5 done echo "下载目录已稳定,所有文件下载完成"
注意:这个方案依赖文件修改时间稳定,适合批量下载时文件修改时间不再变化的场景,但如果有文件下载完成后又被修改的情况,可能会误判,不如AppleScript方案可靠。
方案3:结合fswatch与文件大小校验
用fswatch监控目录变化,同时校验所有文件的大小是否稳定(需要先安装fswatch:brew install fswatch):
#!/bin/bash dir="/Users/ifxl/Downloads/tmp_images/ref/" test -d "${dir}" || exit 1 # 获取当前目录所有文件的大小哈希 get_file_hash() { find "${dir}" -type f -exec stat -f "%z %N" {} \; | shasum -a 256 | awk '{print $1}' } last_hash=$(get_file_hash) current_hash="" # 用fswatch等待目录有变化,然后再校验 while true; do fswatch -1 "${dir}" > /dev/null sleep 2 # 等待文件写入完成 current_hash=$(get_file_hash) if [ "$last_hash" = "$current_hash" ]; then echo "所有文件下载完成,大小稳定" break fi last_hash=$current_hash done
这个方案通过文件大小和路径的哈希值来判断文件是否稳定,避免了修改时间的问题,但需要额外安装fswatch。
内容的提问来源于stack exchange,提问作者Xiang Chen
相关产品推荐
相关产品推荐

