将命令从 Windows Python 脚本传递到 WSL Shell

发布于 2025-01-09 04:45:31 字数 895 浏览 1 评论 0原文

我在 Windows 上使用 PowerShell 和 WSL“Ubuntu 20.04 LTS”。我没有本机 Linux 发行版,并且由于嵌套设备原因,我无法使用虚拟化。

我的目的是在 PowerShell 中使用 Windows Python 脚本调用 WSL 将一些 avd 快照解密为原始图像。我已经尝试过 os.popensubprocess.Popen/run/callwin32com.client< /code>、multiprocessing 等。

我可以启动 WSL shell,但没有进一步的命令传递给它。有人知道如何使 shell 成为焦点并准备更多说明吗?

代码示例:

from multiprocessing import Process
import win32com.client
import time, os, subprocess

def wsl_shell():
    shell = win32com.client.Dispatch("wscript.shell")
    shell.SendKeys("Start-Process -FilePath C:\\Programme\\WindowsApps\\CanonicalGroupLimited.Ubuntu20.04onWindows_2004.2021.825.0_x64__79rhkp1fndgsc\\ubuntu2004.exe {ENTER}")
    time.sleep(5)
    os.popen("ls -l")
    
if __name__ == '__main__':
    ps = Process(target = wsl_shell)
    ps.start()

I'm on Windows using PowerShell and WSL 'Ubuntu 20.04 LTS'. I have no native Linux Distro, and I cant use virtualisation because of nested device reasons.

My purpose is to use a Windows Python script in PowerShell to call WSL to decrypt some avd-snapshots into raw-images. I already tried os.popen, subprocess.Popen/run/call, win32com.client, multiprocessing, etc.

I can boot the WSL shell, but no further commands are getting passed to it. Does somebody know how to get the shell into focus and prepared for more instructions?

Code Example:

from multiprocessing import Process
import win32com.client
import time, os, subprocess

def wsl_shell():
    shell = win32com.client.Dispatch("wscript.shell")
    shell.SendKeys("Start-Process -FilePath C:\\Programme\\WindowsApps\\CanonicalGroupLimited.Ubuntu20.04onWindows_2004.2021.825.0_x64__79rhkp1fndgsc\\ubuntu2004.exe {ENTER}")
    time.sleep(5)
    os.popen("ls -l")
    
if __name__ == '__main__':
    ps = Process(target = wsl_shell)
    ps.start()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

另类 2025-01-16 04:45:31

有几种方法可以从 Windows Python 运行 WSL 脚本/命令,但基于 SendKeys 的方法通常是最后的手段,恕我直言,因为它:

  • 通常是不确定的
  • 缺乏任何控制逻辑

另外,避免ubuntu2004.exe(或者,对于发现此命令的其他用户,已弃用的 bash.exe 命令)。您正在寻找功能更强大的 wsl.exe 命令。它有很多用于运行 .exe 版本所缺少的命令的选项。

考虑到这一点,这里有一些简化的示例:


使用 os.system
import os
os.system('wsl ~ -e sh -c "ls -l > filelist.txt"')

在 Windows Python 中运行此代码后,进入您的 Ubuntu WSL 实例,您应该会找到 filelist.txt > 在你的主目录中。

这是有效的,因为:

  • os.system 可用于启动 wsl 命令
  • ~ 告诉 WSL 在用户的主目录中启动(更具确定性) ,同时能够避免在这种情况下指定每个路径)
  • wsl -e sh 在 WSL 中运行 POSIX shell(您也可以使用 bash
  • 实现 此目的) -c向 shell 添加“” 在 WSL shell 中运行这些命令

鉴于此,您几乎可以从 Windows Python 运行任何 Linux 命令。对于多个命令:

  • 用分号分隔它们。例如:

    os.system('wsl ~ -e sh -c "ls -l > filelist.txt; gzip filelist.txt')
    
  • 或者更好,只需将它们全部放入 WSL 中的脚本中(使用 shebang 行),将其设置为可执行文件,然后通过以下方式运行脚本:

    wsl -e /path/to/script.sh
    

    这甚至可能是一个 Linux Python 脚本(假设脚本中的 shebang 行正确):

    wsl -e /path/to/script.py
    

    因此,如果需要,您甚至可以通过这种方式从 Windows Python 调用 Linux Python。


使用 subprocess.run

os.system 语法非常适合“即发即忘”脚本,您不需要在 Python 中处理结果,但通常您会想要捕获 WSL/Linux 命令的输出以在 Python 中进行处理。

为此,请使用 subprocess.run

import subprocess
cp = subprocess.run(["wsl", "~", "-e", "ls", "-l"], capture_output=True)
print(cp.stdout)

与之前一样,-e 参数可以是您想要的任何类型的 Linux 脚本。

请注意,subprocess.run 还为您提供命令的退出状态。

There are a few ways of running WSL scripts/commands from Windows Python, but a SendKeys-based approach is usually the last resort, IMHO, since it's:

  • Often non-deterministic
  • Lacks any control logic

Also, avoid the ubuntu2004.exe (or, for other users who find this, the deprecated bash.exe command). The much more capable wsl.exe command is what you are looking for. It has a lot of options for running commands that the <distroname>.exe versions lack.

With that in mind, here are a few simplified examples:


Using os.system
import os
os.system('wsl ~ -e sh -c "ls -l > filelist.txt"')

After running this code in Windows Python, go into your Ubuntu WSL instance and you should find filelist.txt in your home directory.

This works because:

  • os.system can be used to launch the wsl command
  • The ~ tells WSL to start in the user's home directory (more deterministic, while being able to avoid specifying each path in this case)
  • wsl -e sh runs the POSIX shell in WSL (you could also use bash for this)
  • Passing -c "<command(s)>" to the shell runs those commands in the WSL shell

Given that, you can pretty much run any Linux command(s) from Windows Python. For multiple commands:

  • Either separate them with a semicolon. E.g.:

    os.system('wsl ~ -e sh -c "ls -l > filelist.txt; gzip filelist.txt')
    
  • Or better, just put them all in a script in WSL (with a shebang line), set it executable, and run the script via:

    wsl -e /path/to/script.sh
    

    That could even be a Linux Python script (assuming the correct shebang line in the script):

    wsl -e /path/to/script.py
    

    So if needed, you can even call Linux Python from Windows Python this way.


Using subprocess.run

The os.system syntax is great for "fire and forget" scripts where you don't need to process the results in Python, but often you'll want to capture the output of the WSL/Linux commands for processing in Python.

For that, use subprocess.run:

import subprocess
cp = subprocess.run(["wsl", "~", "-e", "ls", "-l"], capture_output=True)
print(cp.stdout)

As before, the -e argument can be any type of Linux script you want.

Note that subprocess.run also gives you the exit status of the command.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文