Uncategorized

Passing Commands to the WSL Shell from a Windows Python Script



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.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *