Showing Posts From
Windows
Windows 杀进程:按 PID / 按名字 / 按端口
Windows 上要杀个后台跑的进程,图形界面点半天不如命令行一条搞定。 按 PID 杀(最常用) CMD taskkill /PID 1234 /F1234 换成你的 PID /F 强制结束,不加有时杀不掉PowerShell Stop-Process -Id 1234 -Force不知道 PID 怎么办 按名字找 tasklist | findstr nginx按端口找(比如 8080 被占了) netstat -ano | findstr :8080最后一列就是 PID。也可以直接: Get-NetTCPConnection -LocalPort 8080 | Select-Object OwningProcess按进程名批量杀 嫌一个个找 PID 麻烦: taskkill /IM nginx.exe /F或者 PowerShell 通配: Stop-Process -Name "nginx" -Force杀不掉的情况 碰到 拒绝访问 / Access is denied,先看是不是这几种:权限不够——右键 CMD/PowerShell "以管理员身份运行" SYSTEM 保护进程——比如 System、Registry 是杀不掉的,动它系统会重启 进程被驱动挂钩——某些安全软件会保护自身进程,得先从安全软件里退出进程有子进程且需要一起清理时: taskkill /PID 1234 /T /F/T = 连同子进程一起杀。 一张表速查目的 命令按 PID 杀 taskkill /PID <pid> /F按进程名杀 taskkill /IM <name>.exe /F连子进程一起杀 taskkill /PID <pid> /T /F查端口占用 netstat -ano | findstr :<port>查进程名 tasklist | findstr <name>PowerShell 版本 Stop-Process -Id <pid> -Force
PID 和端口互查:Linux 和 Windows 的常用命令
调试服务、清理端口占用、看某个进程到底连了哪儿——PID 和端口互查是日常操作。整理一份速查。 Linux:按端口找 PID 现代系统首选 ss(netstat 老了,很多发行版默认不装): ss -lntp | grep :8080输出: LISTEN 0 128 *:8080 *:* users:(("java",pid=12345,fd=45))PID 就是 12345。要看 UDP 加 -u,全协议 ss -tulnp。 lsof 也行,输出更清楚: sudo lsof -i:8080Linux:按 PID 找端口 ss -tunp | grep "pid=12345"或者: sudo lsof -Pan -p 12345 -i后者会同时列出该进程的所有连接(监听 + 已连接),排查网络问题特别顺手: COMMAND PID USER FD TYPE DEVICE NAME java 12345 root 45u IPv4 TCP *:8080 (LISTEN) java 12345 root 46u IPv4 TCP 10.0.0.5:8080->8.8.8.8:443 (ESTABLISHED)Linux:查所有监听端口 ss -lntp # TCP ss -lunp # UDP ss -tulnp # 全部Windows:按端口找 PID netstat -ano | findstr :8080输出最后一列是 PID。看进程名: tasklist | findstr 12345PowerShell 版本更直观: Get-NetTCPConnection -LocalPort 8080 | Select-Object LocalAddress, State, OwningProcess | Format-TableWindows:按 PID 找端口 netstat -ano | findstr 12345PowerShell: Get-NetTCPConnection | Where-Object OwningProcess -eq 12345Docker 里的进程 服务在容器里跑,宿主机 ss 只看到 docker-proxy。有两种方式: 宿主机上看容器映射: docker ps --format 'table {{.Names}}\t{{.Ports}}'进容器里看真实进程: docker exec -it <container> ss -lntpWindows:把占端口的进程杀掉 一条链: for /f "tokens=5" %a in ('netstat -ano ^| findstr :8080 ^| findstr LISTENING') do taskkill /PID %a /F或者 PowerShell: Get-NetTCPConnection -LocalPort 8080 | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }Linux:一条命令连查带杀 sudo fuser -k 8080/tcpfuser 会把所有占用 8080/TCP 的进程直接杀掉,慎用。 一个小坑:找不到 PID Linux 上 ss 或 lsof 有时看不到 PID: users:(("java",pid=?,fd=?))多半是没加 sudo——别的用户的进程只有 root 能看。 Windows 上 netstat -ano 看到 PID 4 的东西一般是内核网络栈(System 进程),不是你的应用。 一句话总结 Linux 用 ss -lntp + lsof,Windows 用 netstat -ano + tasklist。PowerShell 用户直接上 Get-NetTCPConnection 更顺。
Redis 在 Windows 上注册为系统服务的两种方式
Redis 官方本身不出 Windows 版,只能靠社区移植版或者 WSL / Docker。想让它随开机启动,两条路。 方式一:tporadowski 移植版自带的服务参数 先下载 tporadowski/redis 的 zip,解压到 D:\Redis,目录里应该有: redis-server.exe redis-cli.exe redis.windows.conf管理员打开 CMD: cd /d D:\Redis redis-server.exe --service-install redis.windows.conf --service-name Redis redis-server.exe --service-start查看服务状态: sc query Redis或者 services.msc 里能看到"Redis"服务。 设置自动启动(默认就是): sc config Redis start= auto注意 start= 和 auto 之间必须有空格。 测试: redis-cli.exe ping返回 PONG 说明装好了。 停止 / 卸载: redis-server.exe --service-stop redis-server.exe --service-uninstall版本不支持 --service-install 的情况 装某些新版本时(例如 Redis 7.4.x 的某些 Windows 编译版)执行 --service-install 会报: *** FATAL CONFIG FILE ERROR (Redis 7.4.7) *** Reading the configuration file, at line 2 >>> 'service-install "redis.conf"' Bad directive or wrong number of arguments原因:这个版本不支持 --service-* 参数,redis-server.exe 直接把 --service-install 当成配置项塞进 conf 里解析,才报"错误指令"。 验证一下: redis-server.exe --help帮助里没有 --service-install / --service-start 就说明确实不支持。这时候上方式二。 方式二:NSSM 包装(通用兜底) NSSM 是个通用的 "把任何程序包成 Windows 服务" 的小工具。 管理员 CMD: nssm install redis弹出 GUI,填三项: Path: D:\Redis\redis-server.exe Startup directory: D:\Redis Arguments: D:\Redis\redis.conf保存后: nssm start redis日志、重启策略、依赖都能在 NSSM 里配。 验证 Redis 真的在监听 netstat -ano | findstr 6379看到: TCP 0.0.0.0:6379 LISTENING就通了。 一句话总结 有 --service-install 就用它、没有就用 NSSM,Windows 上把 Redis 装成开机服务这事就这两条路。
Windows 开机自启:脚本、EXE、Python 服务的四种做法
Windows 上"开机自启"根据程序性质要选不同方式。一股脑塞启动文件夹经常出问题——GUI 程序有个 UAC 弹窗、脚本要读用户目录、长驻服务要跑在 SYSTEM 下——分类拆开来看。 方式一:启动文件夹(普通程序) Win + R 打开: shell:startup这是当前用户的启动目录。把 .exe 或 .lnk 快捷方式扔进去就行。全用户共用: shell:common startup局限:用户登录后才启动 弹 UAC 会需要手动点 关了窗口就没了适合:桌面小工具、常用软件(VSCode、Chrome 等已经自带这个)。 方式二:NSSM 把脚本包成服务(推荐) 长驻的 Python、Node、FastAPI、Uvicorn 等脚本,最省心是用 NSSM。它能把任何 exe/bat/脚本包装成 Windows 服务。 管理员 CMD: nssm install MyService弹出 GUI,填三项: Application → Path: C:\Python311\python.exe Application → Arguments: -m uvicorn main:app --host 0.0.0.0 --port 8000 Application → Startup directory: D:\project设自动启动: sc config MyService start= auto(start= 和 auto 之间必须有空格。) 启动 / 停止 / 删除: net start MyService net stop MyService nssm remove MyService confirmNSSM 的好处:崩溃自动重启(Details 里配 Exit Action) stdout / stderr 可以重定向到日志文件 支持环境变量、依赖、恢复策略 卸载干净方式三:原生 sc create(真 EXE 程序) 已经写成了 Windows Service 兼容的 EXE: sc create MyService binPath= "D:\app\server.exe" start= auto sc start MyService sc delete MyService局限:只能接已经实现了 ServiceMain 的 EXE 普通脚本用这个会秒退,要靠 NSSM方式四:任务计划程序(脚本 / GUI / 用户上下文) 需要在用户登录后启动、或者要 GUI、或者 SYSTEM 下跑不了的: schtasks /create /tn "MyTask" ^ /tr "C:\Users\me\bin\worker.py" ^ /sc onlogon场景:只登录时启动:/sc onlogon 每次开机(不管登录):/sc onstart(需要管理员) 每天 03:00:/sc daily /st 03:00管理: schtasks /query /tn "MyTask" schtasks /run /tn "MyTask" schtasks /delete /tn "MyTask" /f选哪一种场景 推荐只想开机跑一次的桌面程序 启动文件夹Python/Node 长驻脚本、API、爬虫 NSSM(默认选它)已经是 Windows Service 兼容 EXE sc createGUI 程序、要用户桌面 session 任务计划 onlogon系统级、无用户登录也要跑 任务计划 onstart 或 NSSM一句话总结 长驻脚本 = NSSM,开机自动、崩溃自愈、日志齐全。其它类型再按上面表格分。
PowerShell 设置环境变量:临时、当前用户、系统级
PowerShell 里改环境变量有三档:当前会话、当前用户永久、系统级永久,权限和作用范围各不相同。搞混了一堆脚本会失效。 临时(仅当前 PowerShell 窗口) $env:MY_TOKEN = "secret" echo $env:MY_TOKEN只影响当前会话 关掉窗口就没了 90% 的临时脚本调试用这个就够对子进程也生效: $env:PYTHONPATH = "D:\repo\src" python main.py # main.py 里能读到永久(当前用户) [System.Environment]::SetEnvironmentVariable("MY_TOKEN", "secret", "User")写到注册表 HKCU\Environment 新开的进程能读到 当前 PowerShell 窗口需要重开 才能通过 $env:MY_TOKEN 看到不重开也想立刻用的话: $env:MY_TOKEN = "secret" # 先本地设一份永久(系统级) 需要管理员 PowerShell: [System.Environment]::SetEnvironmentVariable("MY_TOKEN", "secret", "Machine")写到 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment 所有用户都能读到 用于系统服务、多用户共享配置读取和删除 读: $env:MY_TOKEN [System.Environment]::GetEnvironmentVariable("MY_TOKEN", "User") [System.Environment]::GetEnvironmentVariable("MY_TOKEN", "Machine")删(把值设为空字符串就是删除): [System.Environment]::SetEnvironmentVariable("MY_TOKEN", $null, "User")追加到 PATH 写 PATH 一定要先读旧的再拼,不然会把系统原本的 PATH 覆盖掉: $old = [System.Environment]::GetEnvironmentVariable("Path", "User") $new = "$old;C:\Users\me\bin" [System.Environment]::SetEnvironmentVariable("Path", $new, "User")去重和验证: $new.Split(";") | Sort-Object -Unique三档对比目标 写法 生效范围只当前窗口 $env:X = "v" 当前会话 + 子进程当前用户永久 [Environment]::SetEnvironmentVariable("X","v","User") 新开进程,用户级系统级永久(管理员) [Environment]::SetEnvironmentVariable("X","v","Machine") 新开进程,所有用户老 Windows API:setx 老一辈 Windows 用 setx: setx MY_TOKEN secret # 用户 setx MY_TOKEN secret /M # 系统(管理员)坑:有 1024 字符限制,PATH 老长了会被截断 也不影响当前窗口一般还是推荐 [Environment]::SetEnvironmentVariable。 一句话总结 会话内 $env:X;永久用 [Environment]::SetEnvironmentVariable,第三参数 "User" 或 "Machine" 决定作用域。改 PATH 记得先读再拼。
Windows 报 WinError 206 路径太长?三种彻底解法
Python 里跑数据集处理,Windows 突然崩: FileNotFoundError: [WinError 206] 文件名或扩展名太长。: 'cache\\vendor\\dataset_2026\\...\\CAM_FRONT_WIDE_H110_HR\\virtual_image'不是数据太大,是这个路径字符串太长——超过了 Windows 老古董的 MAX_PATH = 260 限制。分批读取、分段处理、分次遍历都没用,open() 那一刻就已经炸了。 方案一:开注册表长路径支持(一次性) Windows 10/11 内核其实支持长路径,但默认关着。管理员 PowerShell: New-ItemProperty ` -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" ` -Name "LongPathsEnabled" ` -Value 1 ` -PropertyType DWORD ` -Force或 CMD: reg add HKLM\SYSTEM\CurrentControlSet\Control\FileSystem ^ /v LongPathsEnabled /t REG_DWORD /d 1 /f重启电脑,或者至少重启 Python / IDE 让新进程读到设置。 注意:仅这一步对某些老 Python API、部分 C 扩展、zipfile、shutil 不一定生效——它们内部还在走 260 限制的老 API。 方案二:\\?\ 前缀(最稳) Windows 内核 API 支持超长路径,但要显式加 \\?\ 前缀: import osdef win_long_path(path: str) -> str: """把路径转成支持超长的形式""" p = os.path.abspath(path) if not p.startswith("\\\\?\\"): p = "\\\\?\\" + p return pwith open(win_long_path(long_path)) as f: ...关键点:必须是绝对路径,\\?\ 不认相对路径 全程用反斜杠 \,不能混用正斜杠 UNC 路径(\\server\share\...)要写成 \\?\UNC\server\share\...这是数据管线、爬虫抓文件时最常用的做法,不依赖系统设置。 方案三:从源头缩短 工程上最优雅的还是让路径变短,两个方向: 把项目往盘根挪 D:\workspace\company_project\data\cache\... ❌ D:\d\cache\... ✅ 少几十字符缩短目录命名 自动生成的目录名往往长得离谱: CAM_PBQ_FRONT_WIDE_RESET_OPTICAL_H110_HR ❌ CAM1 ✅用一个 mapping 文件记录原名 → 短名即可。 npm / git 也会踩 不止 Python:git clone 遇到超深仓库 → 加: git config --system core.longpaths truenpm install / pnpm install 的 node_modules 层级太深 → 系统开 LongPathsEnabled + 项目挪到盘根一句话总结 **能开注册表就开、能加 \\?\ 就加、能挪盘根就挪。** 三管齐下才彻底摆脱 WinError 206。
Windows 追加目录到 PATH:CMD 和 PowerShell 的正确姿势
Windows 上装完 Maven / Java / Python,最常做的一件事就是把 bin 目录塞进 PATH。老一辈教程都写 setx PATH "%PATH%;...",看着能跑,实际有个特别坑的边界。 CMD 方式:setx 追加到当前用户 PATH: setx PATH "%PATH%;D:\soft\apache-maven-3.9.15\bin"追加到系统 PATH(需要管理员 CMD): setx /M PATH "%PATH%;D:\soft\apache-maven-3.9.15\bin"新开的 CMD 才能读到。当前窗口立即用: set PATH=%PATH%;D:\soft\apache-maven-3.9.15\bin mvn -vsetx 的两个坑 1. 会展开 %PATH%,把用户和系统 PATH 混起来 %PATH% 在 CMD 里是 系统 + 用户 PATH 的合并结果。你 setx PATH "%PATH%;X" 会把两份合起来写到用户 PATH 里,重复且混乱。 2. 1024 字符截断 setx 有个硬伤:值超过 1024 字符会静默截断。老系统 PATH 已经很长,一次 setx 直接把后半段吞掉。 PowerShell 方式(推荐) [Environment]::SetEnvironmentVariable 更精确——读用户就读用户、写用户就写用户,也没 1024 字符限制。 追加到当前用户 PATH: $addPath = "D:\soft\apache-maven-3.9.15\bin" $current = [Environment]::GetEnvironmentVariable("Path", "User")if ($current -notlike "*$addPath*") { [Environment]::SetEnvironmentVariable("Path", "$current;$addPath", "User") Write-Host "已追加:$addPath" } else { Write-Host "PATH 已存在该目录" }-notlike "*X*" 防止重复添加 "User" 参数明确只改用户 PATH,不动系统 PATH追加到系统 PATH(管理员 PowerShell): $addPath = "D:\soft\apache-maven-3.9.15\bin" $current = [Environment]::GetEnvironmentVariable("Path", "Machine") if ($current -notlike "*$addPath*") { [Environment]::SetEnvironmentVariable("Path", "$current;$addPath", "Machine") }当前会话立刻生效: $env:Path += ";D:\soft\apache-maven-3.9.15\bin" mvn -v通用检查 # 看用户 PATH [Environment]::GetEnvironmentVariable("Path", "User") -split ";"# 看系统 PATH [Environment]::GetEnvironmentVariable("Path", "Machine") -split ";"# 看合并后的 PATH $env:Path -split ";"去重: $env:Path -split ";" | Where-Object { $_ } | Sort-Object -Unique移除某条 用户 PATH 里删掉某条: $remove = "D:\soft\apache-maven-3.9.15\bin" $paths = ([Environment]::GetEnvironmentVariable("Path","User") -split ";") | Where-Object { $_ -ne $remove -and $_ } [Environment]::SetEnvironmentVariable("Path", ($paths -join ";"), "User")一句话总结CMD 只是想加一条:setx PATH "%PATH%;X",小心 1024 截断 认真加:管理员 PowerShell + [Environment]::SetEnvironmentVariable 显式指定 User/Machine 加完记得新开终端才能读到;当前窗口用 $env:Path += ";X"
一个 bat 脚本清 Windows 的 Temp 目录
Windows 用久了 C:\Users\<你>\AppData\Local\Temp 里能塞几 GB 垃圾——浏览器缓存、安装包解压残留、Office 恢复文件。用图形界面点很慢,一个 bat 脚本清完事。 最省事版本 用系统自带的 %TEMP% 变量,不用自己拼路径: @echo off setlocalecho 当前用户: %USERNAME% echo Temp 目录: %TEMP%del /f /s /q "%TEMP%\*" >nul 2>&1 for /d %%p in ("%TEMP%\*") do rmdir /s /q "%%p" >nul 2>&1echo 清理完成 pause拆开看:del /f /s /q — 强制、递归、静默删除文件 for /d ... rmdir /s /q — 遍历所有子目录并递归删除 >nul 2>&1 — 屏蔽所有输出(正在使用的文件删不掉会报一堆红字,太吵)存成 clean-temp.bat,双击就跑。 显式指定用户 Temp 有时想清另一个账户的 Temp,或者用完整路径更保险: @echo off setlocalset USER_NAME=%USERNAME% set USER_TEMP=C:\Users\%USER_NAME%\AppData\Local\Tempecho 清理目录: %USER_TEMP%del /f /s /q "%USER_TEMP%\*" >nul 2>&1 for /d %%p in ("%USER_TEMP%\*") do rmdir /s /q "%%p" >nul 2>&1echo 完成 pause顺便清系统 Temp(需要管理员) C:\Windows\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>&1自动申请管理员权限 想双击就自动 UAC 提升,脚本开头加: @echo off :: 检查是否管理员,不是就重新以管理员启动 net session >nul 2>&1 if %errorlevel% neq 0 ( powershell -Command "Start-Process '%~f0' -Verb RunAs" exit /b )setlocal del /f /s /q "%TEMP%\*" >nul 2>&1 for /d %%p in ("%TEMP%\*") do rmdir /s /q "%%p" >nul 2>&1 del /f /s /q "C:\Windows\Temp\*" >nul 2>&1 echo 完成 pause计划任务:开机自动清 想让开机就跑: schtasks /create /tn "CleanTemp" /tr "C:\path\to\clean-temp.bat" /sc onlogon或者每天 3 点跑: schtasks /create /tn "CleanTemp" /tr "C:\path\to\clean-temp.bat" /sc daily /st 03:00删除任务: schtasks /delete /tn "CleanTemp" /f会看到的"报错" 跑完总有一堆"访问被拒绝"或"文件被占用"——这是正常的。有些文件是 Chrome、微信、系统服务在用,删不掉就是删不掉,重启后再跑一遍即可。 要看进度,把 >nul 2>&1 去掉就能看到每一步: del /f /s /q "%TEMP%\*"别做的事不要清 C:\Windows 下的其它目录,会把系统搞坏 不要开 del /q "C:\*" /s,字面意思 少用 rmdir /s /q C:\Windows\Temp 整个删掉目录本身——某些系统组件会因为找不到目录而报错一句话总结 del %TEMP%\* + for /d %%p rmdir %%p 就是 Temp 清理的核心两行。加个自动 UAC 和计划任务,就能忘掉这事。
