Windows bat 脚本清理 Temp 目录:%TEMP% 变量与 del/rmdir 用法
用 %TEMP% 清理当前用户临时目录 @echo off setlocalecho 当前用户: %USERNAME% echo Temp目录: %TEMP%:: 删除文件(/f 强制 /s 子目录 /q 静默) del /f /s /q "%TEMP%\*" >nul 2>&1:: 删除空文件夹 for /d %%p in ("%TEMP%\*") do rmdir /s /q "%%p" >nul 2>&1echo 清理完成 pause%TEMP% 是 Windows 内建变量,直接指向当前用户的临时目录(通常是 C:\Users\用户名\AppData\Local\Temp),不需要手动拼路径。 同时清理系统 Temp(需管理员) @echo off setlocal:: 用户 temp del /f /s /q "%TEMP%\*" >nul 2>&1 for /d %%p in ("%TEMP%\*") do rmdir /s /q "%%p" >nul 2>&1:: 系统 temp(需要管理员权限运行) del /f /s /q "C:\Windows\Temp\*" >nul 2>&1 for /d %%p in ("C:\Windows\Temp\*") do rmdir /s /q "%%p" >nul 2>&1echo 清理完成 pause手动拼接路径写法 如果需要明确用户名,也可以用 %USERNAME% 拼路径: set USER_TEMP=C:\Users\%USERNAME%\AppData\Local\Tempdel /f /s /q "%USER_TEMP%\*" >nul 2>&1 for /d %%p in ("%USER_TEMP%\*") do rmdir /s /q "%%p" >nul 2>&1两种写法效果一致,推荐用 %TEMP% 更简洁。 常见问题 部分文件删不掉 正常现象。系统正在使用的文件(如浏览器缓存、日志)不会被删,>nul 2>&1 会把错误输出吞掉,脚本继续执行,不影响其他文件的清理。 清理完大小没变化 有些文件夹包含只读属性文件。可以在 del 前加 /a 参数(包含只读): del /f /s /q /a "%TEMP%\*" >nul 2>&1不要手动清 C:\Windows\System32\config\systemprofile\AppData\Local\Temp,这是系统服务的临时目录。 设为计划任务定期执行把脚本保存为 clean_temp.bat 打开"任务计划程序"(Task Scheduler) 创建基本任务 → 触发器选"登录时"或"每周" 操作选"启动程序" → 指向 clean_temp.bat 权限选"使用最高权限运行"这样每次登录自动清理,免手动执行。
JSC 文件分析:V8 字节码、bytenode 产物与字符串提取
JSC 文件的三种类型 .jsc 不是一种统一格式,常见有三类:类型 本质 能否反编译bytenode 生成 V8 字节码 基本不能还原源码JavaScriptCore(iOS/WebKit) JSCore 缓存 无稳定通用工具微信小程序 V8 字节码或混淆加密体 几乎不可能还原核心结论:JSC 是编译产物,不是源码压缩。变量名、结构、注释已丢失,不存在完美反编译。 View8 报错原因 RuntimeError: Failed to detect version for file index.jscView8 要先检测 V8 版本,失败通常是这几个原因:文件不是 V8 cache——bytenode 生成的 .jsc 结构与 V8 code cache 不同 .jsc 被加了 header、base64 或 zip 包装 V8 版本超出 View8 支持范围(通常只支持 8.x~11.x)用 Python 快速判断: with open("index.jsc", "rb") as f: print(f.read(32).hex())V8 code cache 开头有固定的 magic bytes。如果头部是乱码或压缩特征,View8 直接放弃。 Python 提取可读字符串 不管是哪种 JSC,都可以先提取二进制文件中的可读字符串,判断是否有逆向价值: import rewith open("index.jsc", "rb") as f: data = f.read()strings = re.findall(rb"[ -~]{6,}", data)seen = set() for s in strings: text = s.decode("utf-8", errors="ignore") if text not in seen: seen.add(text) print(text)正则 [ -~]{6,} 匹配长度 >= 6 的 ASCII 可读字符串。 结果判断:出现 /api/、token、userInfo 等 → 文件未加密,有分析价值 全是乱码 → 已加密或压缩,需换思路bytenode JSC 的运行时分析 bytenode 产物无法静态反编译,但可以在 Node.js 中加载后 hook: require("bytenode");// hook 所有函数调用 const originalCall = Function.prototype.call; Function.prototype.call = function(...args) { if (this.name) { console.log("[call]", this.name, args.slice(0, 2)); } return originalCall.apply(this, args); };require("./index.jsc");或者用 Node.js inspect 调试: node --inspect-brk -e "require('bytenode'); require('./index.jsc')"然后用 Chrome DevTools 连接 chrome://inspect,可以打断点、查看调用栈。 三种方案对比方案 成功率 适用场景Python strings 提取 高(未加密) 快速判断有无价值运行时 hook 高 bytenode 产物Node inspect 调试 高 有 require 入口静态 V8 字节码分析 低 仅作辅助对于加密 JSC(AES/RC4 加密,或微信小游戏自定义 VM),以上方法均不适用,需要先逆向解密逻辑。
JS 获取今天零点并前后偏移 N 小时:Date setHours 与时区格式化
获取今天零点 const now = new Date(); const midnight = new Date(now); midnight.setHours(0, 0, 0, 0);console.log(midnight); // Mon Apr 14 2026 00:00:00 GMT+0800setHours(0, 0, 0, 0) 四个参数分别是小时、分钟、秒、毫秒,全设为 0 就是当天零点(本地时间)。 往后推 N 小时 const now = new Date(); const start = new Date(now); start.setHours(0, 0, 0, 0);const N = 10000; const end = new Date(start.getTime() + N * 60 * 60 * 1000);console.log("开始:", start); console.log("结束:", end); // 10000 小时 ≈ 416 天 + 16 小时后往前推 N 小时 const before = new Date(start.getTime() - N * 60 * 60 * 1000);console.log("今天零点:", start); console.log("往前 10000 小时:", before); // 约 416 天前时区问题:toISOString() 是 UTC console.log(start.toISOString()); // "2026-04-13T16:00:00.000Z" ← UTC 时间,比北京时间少 8 小时toISOString() 始终输出 UTC 时间。中国时区(UTC+8)的零点在 UTC 是前一天 16:00,如果直接用这个输出给后端或用于显示会有偏差。 本地时间格式化: function formatLocal(date) { return [ date.getFullYear(), String(date.getMonth() + 1).padStart(2, "0"), String(date.getDate()).padStart(2, "0") ].join("-") + " " + [ String(date.getHours()).padStart(2, "0"), String(date.getMinutes()).padStart(2, "0"), String(date.getSeconds()).padStart(2, "0") ].join(":"); }console.log(formatLocal(start)); // "2026-04-14 00:00:00" console.log(formatLocal(end)); // "2027-06-30 16:00:00"生成时间序列 K 线拉取、回测等场景需要每小时一个时间点的数组: function generateHourlyRange(startDate, hours) { const step = 60 * 60 * 1000; const arr = []; for (let i = 0; i <= hours; i++) { arr.push(new Date(startDate.getTime() + i * step)); } return arr; }const start = new Date(); start.setHours(0, 0, 0, 0);const range = generateHourlyRange(start, 24); console.log(range.slice(0, 3).map(formatLocal)); // ["2026-04-14 00:00:00", "2026-04-14 01:00:00", "2026-04-14 02:00:00"]往前推的时间序列只需把 + i * step 改成 - i * step。 与后端接口对接 如果后端接受的是 Unix 时间戳(秒): const startTs = Math.floor(start.getTime() / 1000); const endTs = Math.floor(end.getTime() / 1000);fetch(`/api/kline?start=${startTs}&end=${endTs}`)如果后端接受 ISO 字符串(UTC): const params = new URLSearchParams({ start: start.toISOString(), end: end.toISOString() });两者都是基于 getTime() 的毫秒时间戳,不存在时区歧义,只是显示层面需要处理本地时区。
ScriptCat / Tampermonkey 用 GM_xmlhttpRequest 调用 AI 视觉接口
为什么必须用 GM_xmlhttpRequest 用户脚本环境里调用第三方 API,普通 fetch 会被浏览器 CORS 限制卡死。GM_xmlhttpRequest 是油猴环境提供的跨域请求接口,可以绕过这个限制: // ❌ 这样会报 CORS 错误 fetch("https://open.bigmodel.cn/api/paas/v4/chat/completions", {...})// ✅ 用 GM_xmlhttpRequest GM_xmlhttpRequest({ method: "POST", url: "https://open.bigmodel.cn/api/paas/v4/chat/completions", ... })脚本头部必须声明权限: // @grant GM_xmlhttpRequest完整示例:调用视觉模型分析页面图片 // ==UserScript== // @name AI 图片分析 // @namespace http://tampermonkey.net/ // @version 1.0 // @match *://*/* // @grant GM_xmlhttpRequest // ==/UserScript==(function () { const API_KEY = "your-api-key"; // 换成你的 key function getImagesFromPage() { const imgs = document.querySelectorAll("img"); return Array.from(imgs) .slice(0, 3) .map(img => ({ type: "image_url", image_url: { url: img.src || img.dataset.src // 处理懒加载 } })) .filter(item => item.image_url.url); } function requestAI(imageItems) { GM_xmlhttpRequest({ method: "POST", url: "https://open.bigmodel.cn/api/paas/v4/chat/completions", headers: { "Content-Type": "application/json", "Authorization": "Bearer " + API_KEY }, data: JSON.stringify({ model: "glm-4v", messages: [ { role: "user", content: [ ...imageItems, { type: "text", text: "请分析这些图片的内容" } ] } ] }), onload: function (res) { try { const data = JSON.parse(res.responseText); const answer = data?.choices?.[0]?.message?.content; console.log("AI 回答:", answer); alert(answer); } catch (e) { console.error("解析失败", e); } }, onerror: function (err) { console.error("请求失败", err); } }); } const images = getImagesFromPage(); if (images.length > 0) { requestAI(images); } })();图片来源处理 指定区域内的图片 function getQuestionImages() { const container = document.querySelector(".question-area"); if (!container) return []; return Array.from(container.querySelectorAll("img")).map(img => ({ type: "image_url", image_url: { url: new URL(img.getAttribute("src") || "", location.href).href } })); }new URL(src, location.href).href 可以把相对路径补全为绝对 URL。 canvas 图片转 base64 页面是 canvas 渲染(反爬、PDF 等)时,需要截图再传: function getCanvasImage() { const canvas = document.querySelector("canvas"); if (!canvas) return []; return [{ type: "image_url", image_url: { url: canvas.toDataURL("image/png") // data:image/png;base64,... } }]; }大多数视觉模型 API 同时支持 URL 和 base64 格式的图片。 常见问题 GM_xmlhttpRequest is not a function脚本头部没有声明 @grant GM_xmlhttpRequest。 图片 URL 404 / 模型报错 图片 URL 必须能公网访问,localhost、blob:、file:// 都不行 带签名的临时 URL(如 S3 presigned URL)容易过期,建议转 base64@grant none 和 @grant GM_xmlhttpRequest 冲突用了 GM API 就不能同时 @grant none,两者互斥。 绑定到按钮 把 AI 调用绑定到页面按钮,点击时分析当前可见的图片: const btn = document.createElement("button"); btn.textContent = "AI 分析"; Object.assign(btn.style, { position: "fixed", right: "20px", bottom: "20px", padding: "10px 18px", background: "#2563eb", color: "#fff", border: "none", borderRadius: "8px", cursor: "pointer", zIndex: 9999 }); btn.onclick = () => requestAI(getImagesFromPage()); document.body.appendChild(btn);
Docker 拉镜像报 proxyconnect tcp: EOF 的正确解法
宝塔面板上一键部署一个项目,卡在拉镜像那步: Image mysql:8.2 Error Get "https://registry-1.docker.io/v2/": proxyconnect tcp: EOF Error response from daemon: Get "https://registry-1.docker.io/v2/": proxyconnect tcp: EOF关键词是 proxyconnect tcp: EOF——Docker 通过代理连 Docker Hub 时握手就断了。不是网络挂了,是代理配置有问题。 第一步:看 Docker 是不是走代理 docker info | grep -i proxy如果看到类似: HTTP Proxy: http://127.0.0.1:7890 HTTPS Proxy: http://127.0.0.1:7890说明 Docker daemon 被配了代理。接着验证代理是不是能用: curl -x http://127.0.0.1:7890 https://registry-1.docker.io/v2/返回 {} 或认证提示:代理正常 EOF / timeout:代理进程挂了 Connection refused:代理端口没开三个典型场景系统开了 Clash/v2ray,但 Docker daemon 拿不到——Docker 不会自动继承桌面代理,Mac 上尤其容易踩。 代理协议写错——把 http://127.0.0.1:7890 写成了 https://,直接握手失败。 代理软件本身抽风或被墙——重启一下代理再试。解决办法 方案一:临时不走代理 先确认到底是不是代理的锅: unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY docker pull redis:latest拉得下来就是代理问题,不用再折腾 Docker 本身了。 方案二:配国内镜像源(推荐) 编辑 daemon 配置: sudo mkdir -p /etc/docker sudo nano /etc/docker/daemon.json写入: { "registry-mirrors": [ "https://dockerproxy.com", "https://mirror.ccs.tencentyun.com", "https://registry.docker-cn.com" ] }重启: sudo systemctl daemon-reexec sudo systemctl restart docker再拉镜像基本就通了。注意公开镜像源可用性经常变化,实在拉不下来就换一个。 方案三:正确给 Docker 配代理 如果确实需要走代理,别改环境变量,改 systemd 单元: sudo mkdir -p /etc/systemd/system/docker.service.d sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf写入: [Service] Environment="HTTP_PROXY=http://127.0.0.1:7890" Environment="HTTPS_PROXY=http://127.0.0.1:7890" Environment="NO_PROXY=localhost,127.0.0.1"然后: sudo systemctl daemon-reload sudo systemctl restart docker一句话总结 proxyconnect tcp: EOF = Docker 正在走一个 坏掉的代理。先 unset 代理确认锅在哪儿,然后要么配国内镜像源,要么正确写 systemd 代理配置。
