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 thewsl
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 usebash
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.