{"record":{"id":"3e4a7e58bcf0d2a0","repo":"XIU2/CloudflareSpeedTest","slug":"cfst-ip-0-3e4a7e","errorCode":null,"errorMessage":"CFST 测速结果 IP 数量为 0，跳过下面步骤...","messagePattern":"CFST 测速结果 IP 数量为 0，跳过下面步骤\\.\\.\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"script/cfst_hosts.sh","lineNumber":38,"sourceCode":"\t\t\t\tbreak\n\t\t\telse\n\t\t\t\techo \"该 IP 不能是空！\"\n\t\t\tfi\n\t\telse\n\t\t\tbreak\n\t\tfi\n\tdone\n}\n\n_UPDATE() {\n\techo -e \"开始测速...\"\n\tNOWIP=$(head -1 nowip_hosts.txt)\n\n\t# 这里可以自己添加、修改 CFST 的运行参数\n\t./cfst -o \"result_hosts.txt\"\n\n\t# 如果需要 \"找不到满足条件的 IP 就一直循环测速下去\"，那么可以将下面的两个 exit 0 改为 _UPDATE 即可\n\t[[ ! -e \"result_hosts.txt\" ]] && echo \"CFST 测速结果 IP 数量为 0，跳过下面步骤...\" && exit 0\n\n\t# 下面这行代码是 \"找不到满足条件的 IP 就一直循环测速下去\" 才需要的代码\n\t# 考虑到当指定了下载速度下限，但一个满足全部条件的 IP 都没找到时，CFST 就会输出所有 IP 结果\n\t# 因此当你指定 -sl 参数时，需要移除下面这段代码开头的 # 井号注释符，来做文件行数判断（比如下载测速数量：10 个，那么下面的值就设在为 11）\n\t#[[ $(cat result_hosts.txt|wc -l) > 11 ]] && echo \"CFST 测速结果没有找到一个完全满足条件的 IP，重新测速...\" && _UPDATE\n\n\n\tBESTIP=$(sed -n \"2,1p\" result_hosts.txt | awk -F, '{print $1}')\n\tif [[ -z \"${BESTIP}\" ]]; then\n\t\techo \"CFST 测速结果 IP 数量为 0，跳过下面步骤...\"\n\t\texit 0\n\tfi\n\techo ${BESTIP} > nowip_hosts.txt\n\techo -e \"\\n旧 IP 为 ${NOWIP}\\n新 IP 为 ${BESTIP}\\n\"\n\n\techo \"开始备份 Hosts 文件（hosts_backup）...\"\n\t\\cp -f /etc/hosts /etc/hosts_backup\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/XIU2/CloudflareSpeedTest/blob/1da0c025d7b6f9bf0b2b0cf47a547f65430deab2/script/cfst_hosts.sh#L20-L56","documentation":"In cfst_hosts.sh's _UPDATE(), after ./cfst -o result_hosts.txt the existence check at script/cfst_hosts.sh:38 fires when the output file is absent: CFST writes result_hosts.txt only when at least one IP passes its filters, so 'file missing' is equated with '0 qualifying IPs'. The script then exits 0, leaving /etc/hosts untouched and NOWIP (from nowip_hosts.txt) as the active mapping.","triggerScenarios":"Every candidate IP failed the latency/download filters; ./cfst did not actually run (missing binary, not executable, or ip.txt absent in the working directory); outbound 443/80 to Cloudflare ranges blocked so CFST found nothing.","commonSituations":"User tightened -t/-sl/-tl beyond what current Cloudflare IPs satisfy; a cron job whose working directory is not the script directory so ./cfst fails silently; outdated ip.txt after Cloudflare renumbered ranges.","solutions":["Run ./cfst -o result_hosts.txt manually in the script directory and read its output","Verify ./cfst is executable and ip.txt exists; chmod +x cfst if needed","Ease the CFST arguments (higher -t, lower -sl) or update ip.txt and retry","If run from cron, ensure the job cds into the script directory first (or use absolute paths)","To retry instead of skip, follow the file's own comment: replace exit 0 with _UPDATE (guard against tight loops)"],"exampleFix":"# script/cfst_hosts.sh (before)\n./cfst -o \"result_hosts.txt\"\n[[ ! -e \"result_hosts.txt\" ]] && echo \"CFST 测速结果 IP 数量为 0，跳过下面步骤...\" && exit 0\n# (after)\n./cfst -o \"result_hosts.txt\" || { echo \"cfst run failed\" >&2; exit 1; }","handlingStrategy":"retry","validationCode":"[ -x ./cfst ] && [ -f ip.txt ] || { echo 'cfst/ip.txt missing' >&2; exit 1; }\n[ -f nowip_hosts.txt ] || echo 'first run: nowip_hosts.txt absent, NOWIP will be empty' >&2","typeGuard":null,"tryCatchPattern":"./cfst -o result_hosts.txt || { echo \"cfst exited $?\" >&2; exit 1; }","preventionTips":["cd into the script dir in cron: 0 */6 * * * cd /opt/cfst && bash cfst_hosts.sh","Verify the binary runs (chmod +x, ./cfst -h) after every redeploy","Keep the exit-0-on-empty behavior: an unchanged /etc/hosts beats a half-updated one"],"tags":["shell","bash","hosts-file","cloudflare","speedtest","empty-result"],"backgroundTag":null,"analyzedSha":"1da0c025d7b6f9bf0b2b0cf47a547f65430deab2","analyzedAt":"2026-08-15T22:22:10.737Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}