Context:
I have been tasked with researching how to execute linux commands using python. Since I am on windows, I have to execute 'wsl' first to swtich to the ubuntu distro I downloaded from microsoft store. Note that I am not a python programmer but currently working as a java intern. Although the python project/script will be deployed on a linux machine right now this is the only way for me to test the program.
Problem:
The problem I am getting is that if I have an list of commands and I am trying to execute them one by one, for some reason at the end of every command a return carriage is being found because apparently in windows DOS uses carriage return and line feed ("\r\n") as a line ending whereas in linux uses just line feed ("\n").
This is the python script
import subprocess
commands=["ls -al ~","pwd"]
# Initialize the WSL process
process = subprocess.Popen("wsl", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
# Execute each command in WSL
for command in commands:
process.stdin.write((command)+"\n")
# Close the stdin and wait for the process to complete
process.stdin.close()
process.wait()
# Read and print the response from WSL
output = process.stdout.read()
print("WSL:", output)
I tried stripping '\r' but it makes absolutely zero difference as if it doesn't understand what '\r' is. Here is the output:
WSL: ls: cannot access '~'$'\r': No such file or directory
-bash: line 2: $'pwd\r': command not found
Solution 1
write converted \n to \r\n, try this :
import subprocess
commands=["ls -al ~","pwd"]
# Initialize the WSL process
process = subprocess.Popen("wsl", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
# Execute each command in WSL
with open(process.stdin.fileno(), mode='w', newline='') as f:
for command in commands:
f.write((command)+'\n')
# Close the stdin and wait for the process to complete
# process.stdin.close()
# process.wait()
# Read and print the response from WSL
output = process.stdout.read()
print("WSL:", output)
Update: Thanks for the solution but and I also figured out a solution myself. It works like a charm. Solution 2 by questioner
import subprocess
import shlex
# Define a list of commands
commands = ["ls -al ~", "pwd", "pwd"]
# Initialize the WSL process and execute each command
for command in commands:
command_list = shlex.split(command)
#Remove the ['wsl'] if this script is ran in linux environment
#Also I am assuming that the default shell is bash
#If it's not then enter into bash mode(or anyother) by replacing 'wsl' with 'bash'
result = subprocess.run(['wsl'] + command_list, stdout=subprocess.PIPE, text=True)
print("WSL:", result.stdout)
text=Truetopopen? Looks like that's the source of the extra CRs.ls -l. It is a fairly odd thing to execute Linux commands through Python. my advice: for a simple set of commands, use a bash script; for a complicated set of commands, write a proper (Python) programfor command in commands: print(subprocess.run(['wsl'] + shlex.split(command), text=True).stdout)and get rid of the whole attempt to usePopen