如何在WSL2的cron bash脚本中运行Windows可执行文件?
WSL2 cron环境无法执行Windows可执行文件修复方案
cron执行任务时使用无交互的极简运行环境,缺少WSL2调用Windows程序、运行screen等依赖会话上下文的工具所必需的环境变量,因此会出现Linux原生命令(如rsync)可正常运行,但Windows exe、screen命令失效的问题,按以下步骤修改即可:
脚本修改步骤
- 替换脚本开头的环境变量配置段,在原有PATH基础上补全WSL互操作、会话相关的必需变量,修改后脚本开头如下:
#!/bin/bash # 基础PATH配置 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Windows/system32:/mnt/c/Windows:/mnt/c/Windows/System32 # 补全WSL跨系统调用Windows程序核心变量 export WSL_INTEROP=/run/WSL/$(ls -t /run/WSL | grep interop | head -n1) export WSL_DISTRO_NAME=Ubuntu-20.04 # 补全会话相关变量,解决screen启动失败问题 export DISPLAY=$(grep nameserver /etc/resolv.conf | awk '{print $2; exit}'):0 export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus export XDG_RUNTIME_DIR="/run/user/$(id -u)"
注意:
WSL_INTEROP是WSL2跨系统调用的核心通信socket,cron环境默认不携带该变量,且该socket文件名随WSL运行动态生成,上述命令会自动匹配当前最新的有效interop socket。
- 替换脚本中所有Windows可执行文件的调用方式,使用全路径调用,不依赖PATH匹配:
- 原
taskkill.exe /im calibre.exe替换为/mnt/c/Windows/System32/taskkill.exe /im calibre.exe - 其余Windows程序如notepad.exe同理,统一写全路径
/mnt/c/Windows/System32/notepad.exe
- 原
- 修正screen命令的调用写法,去掉多余的转义符,原行修改为:
screen -dm bash -c "/mnt/c/Users/Colin/Desktop/startcalibre.sh"
crontab任务配置修改
不要直接在crontab中裸写脚本路径,修改定时任务行,增加工作目录切换、日志重定向方便排错:
* * * * * cd /home/你的WSL普通用户名 && /bin/bash /mnt/c/Users/Colin/Desktop/test.sh >> /tmp/cron_calibre_sync.log 2>&1
- 该任务必须配置在你的普通用户crontab中(执行
crontab -e编辑时不要加sudo),不要放在root用户的crontab里,否则会因为用户权限上下文不匹配导致跨系统调用失败。 - 配置完成后给两个脚本加可执行权限:
chmod +x /mnt/c/Users/Colin/Desktop/test.sh /mnt/c/Users/Colin/Desktop/startcalibre.sh - 重启cron服务生效:
sudo service cron restart
排错提示
如果修改后仍有异常,直接查看/tmp/cron_calibre_sync.log日志文件中的报错信息即可定位问题,不需要额外抓包排查。
内容的提问来源于stack exchange,提问作者Colin Gordon
相关产品推荐
相关产品推荐

