如何在WSL 2中通过shell(bash)脚本从cronjob运行Windows可执行文件?

0pizxfdo  于 2023-05-29  发布在  Shell
关注(0)|答案(2)|浏览(258)

我正在运行Windows 10 x64和WSL2(Ubuntu 20.04 on WSL2)。
在WSL2中,我让cron运行以下任务:

* * * * * /mnt/c/Users/Colin/Desktop/test.sh

www.example.com的内容test.sh(目前每分钟执行一次,用于测试目的)如下:

#!/bin/bash
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

taskkill.exe /im calibre.exe
sleep 5
<rsync command here>
echo "Done with rsync, launching calibre..."
screen -dm bash -c \"/mnt/c/Users/Colin/Desktop/startcalibre.sh\"

当从WSL2提示符执行时,此脚本可以完美地工作。

**然而,cron不会运行脚本中的taskkill.exe命令或screen命令(启动calibre)。**我确实看到cron执行脚本,因为我看到rsync运行,因为我可以在Wireshark中看到它。WSL2上的cron似乎在运行Windows可执行文件(taskkill.exe等)时存在问题(我甚至无法通过cron执行的脚本启动notepad.exe)。

我应该在脚本中添加什么来让cron执行Windows可执行文件?

nhn9ugyo

nhn9ugyo1#

不一定是答案,但我希望这能让我们找到答案...
首先,让我们尝试一个几乎任何WSL用户都可以运行的脚本,看看我们是否可以在更多的MRE中重现这个问题:

#!/usr/bin/env bash

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

echo $PATH > ~/cronlogger

notepad.exe &
sleep 2
which taskkill.exe >> ~/cronlogger

taskkill.exe /im notepad.exe >> ~/cronlogger 2>&1

我也把这个脚本放在我的%userprofile%/Desktop/test.sh中,并设置它运行相同的crontab行(通过sudo crontab -u ntd -e):

* * * * * /mnt/c/Users/ntd/Desktop/test.sh

正如预期的那样,它对我很有效--每分钟,记事本都会弹出,然后2秒钟后就会被杀掉。~/cronlogger的内容是:

/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
/mnt/c/Windows/system32/taskkill.exe
SUCCESS: Sent termination signal to the process "Notepad.exe" with PID 4268.

当然,要等到分钟顶部后的几秒钟,以确保你捕捉到了整个事情。
我注意到您有两个..\System32路径,但这不重要。此外,区分大小写不是问题,除非您通过/etc/wsl.conf专门为Windows驱动器打开它。
我测试了这个:

  • 在Windows 10 21 H2
  • 在Windows 11上使用最新的WSL预览版
  • 作为我的普通用户sudo crontab -u ntd -e
  • 作为root用户sudo crontab -e

对我来说一切都很好。
在这一点上,我能想到的唯一一件事可能是如果你使用某种类型的Systemd脚本。我看到Systemd丢弃了WSL binfmt_misc注册,这样WSL就不能再运行Windows可执行文件了。我可以想象这可能发生在Cron守护进程中(但仍然通过默认shell工作)。

ma8fv8wu

ma8fv8wu2#

这可能是相关的(但我不知道究竟是什么口径),这是测试的原因,从@NotTheDr01ds不为我工作。
WSL crond通常由Windows任务计划程序启动。如果您选择“无论用户是否登录都运行”选项,则任务调度程序将作为后台进程运行crond,无法生成交互式显示。反过来,这意味着所有由cron启动的进程都将是后台进程。
如果你想用cron启动的进程有任何可见的用户界面,那么你需要在任务调度器中选择“仅在用户登录时运行”来启动cron。

相关问题