I would like to run a command in python using subprocess.run
I would like to switch the working directory JUST for the execution of this command.
Also, I need to record the output and the return code.
Here is the code I have:
import subprocess
result = subprocess.run("echo \"blah\"", cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
but this only returns
FileNotFoundError: [Errno 2] No such file or directory: 'echo "Running ls -la" && ls -la'
I also tried using the following arguments:
subprocess.run(["echo", "\"blah\""], cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Like Jean-François Fabre said, the solution is to add "shell=True" to the call
import subprocess
result = subprocess.run("echo \"blah\"", cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
shell=True seems to tell subprocess to use the string as a command.
Related
This question already has answers here:
Windows can't find the file on subprocess.call()
(7 answers)
Closed 4 months ago.
I'm playing around with subprocess.Popen for shell commands as it seems it has more flexbility with regards to piping compared to subprocess.run
I'm starting off with some simple examples but I'm getting FileNotFoundError:
I was told that shell = True is not necessary if I make the arguments as proper lists. However it doesn't seem to be working.
Here are my attempts:
import subprocess
p1 =subprocess.Popen(['dir'], stdout =subprocess.PIPE)
output = p1.communicate[0]
p = subprocess.Popen([ "dir", "c:\\Users"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
outputs = p.communicate()
Both are leading to FileNotFoundError
As dir is simply a command understood by cmd.exe (or powershell.exe) then you could:
subprocess.Popen(["cmd", "/c", "dir", "c:\\Users"], stdout=subprocess.PIPE)
which corresponds to doing the following in a shell
C:\>cmd /c dir c:\Users
You may find you have to fully path cmd, as c:\\Windows\\System32\\cmd.exe
Your problem is that "dir" is an internal Windows command and your "popen" is looking for the name of an executable. You could try setting up a "dir.bat" file that runs the "dir" command to see if this works or simply try any of the commands in \Windows\system32 instead.
Try this (on windows):
import subprocess
file_name = "test.txt"
sp = subprocess.Popen(["cmd", "/c", 'dir', '/s', '/p', file_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = sp.communicate()
output = output[1].decode()
if file_name in output:
print("yes")
else:
print("no")
On Linux, replace the call to subprocess like this:
sp = subprocess.Popen(['find', '-name', file_name, '/'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
I htink the key is in: stdout=subprocess.PIPE, stderr=subprocess.PIPE
I have a file: "abc", it's a executable file.
I want to execute it by Phthon or windows CMD.
If I write code:
subprocess.Popen('-a -b -c', creationflags=0x08, shell=True, executable="C:\\abc")
Then, abc executed, but params(-a -b -c) been ignored
So...How Can I reslove it?
Why not change your code to the following version
args = ['C:\\abc', '-a', '-b', '-c']
p = subprocess.Popen(' '.join(args), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
or without shell=True you can further reduce it to
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
or you can use another method to get output from your exe and pass arguments to it
Output = subprocess.check_output(' '.join(args), shell=True).decode()
Finally, I found the answer myself, which is to use win32process.CreateProcess
Thanks to other authors, but their answers are wrong.
The correct answer is:
win32process.CreateProcess(r"C:\abc", "-a -b -c", None, None, 0, 0, None, None, win32process.STARTUPINFO())
The following answer does not work:
subprocess.Popen('-a -b -c', creationflags=0x08, shell=True, executable="C:\\abc")
#or
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Maybe I really don’t know how to use subprocess, but Windows is really special. Executable files without a suffix cannot be executed directly on the command line.
In PowerShell
& "C:\abc.exe"
Hey i'm trying to run a shell Script with python using the Following lines:
import subprocess
shellscript = subprocess.Popen(["displaySoftware.sh"], stdin=subprocess.PIPE)
shellscript.stdin.write("yes\n")
shellscript.stdin.close()
returncode = shellscript.wait()
But when I run the Program it says that it can't find the .sh file.
Your command is missing "sh", you have to pass "shell=True" and "yes\n" has to be encoded.
Your sample code should look like this:
import subprocess
shellscript = subprocess.Popen(["sh displaySoftware.sh"], shell=True, stdin=subprocess.PIPE )
shellscript.stdin.write('yes\n'.encode("utf-8"))
shellscript.stdin.close()
returncode = shellscript.wait()
This method might be better:
import subprocess
shellscript = subprocess.Popen(["displaySoftware.sh"], shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
returncode = shellscript.communicate(input='yes\n'.encode())[0]
print(returncode)
When running this on my machine the "displaySoftware.sh" script, that is in the same directory as the python script, is successfully executed.
I want to delete all the below files:
20200922_051424_00011_v4wzh_db508ed0-b8b9-488b-a796-773d1fb4045c_08
20200922_051424_00011_v4wzh_db508ed0-b8b9-488b-a796-773d1fb4045c_04 20200922_051424_00011_v4wzh_db508ed0-b8b9-488b-a796-773d1fb4045c_09
20200922_051424_00011_v4wzh_db508ed0-b8b9-488b-a796-773d1fb4045c_05 20200922_051424_00011_v4wzh_db508ed0-b8b9-488b-a796-773d1fb4045c_10
In Linux I simply do:
rm 20200922_051424_00011_v4wzh_db508ed0-b8b9-488b-a796-773d1fb4045c_*
But when I am doing the same using python script. It is just deleting first file matching the pattern but not all of them:
temp = subprocess.Popen('rm 20200922_051424_00011_v4wzh_db508ed0-b8b9-488b-a796-773d1fb4045c_*', shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Can anyone tell me the reason why its not working and also what should I do?
Complete python function is:
def remove(filename):
try:
cmd = 'rm ' + filename
print(cmd)
temp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = temp.communicate()
if stderr:
print('Error while running rm command.')
print("Result of running rm command: ", stdout)
except CalledProcessError as e:
pass
Since you're in python, why not remove them directly from python rather than calling a shell command?
for filename in glob.glob(pattern):
os.remove(filename)
Documentation:
os.remove()
glob.glob()
Whenever i call a c code executable from Python using the method below I get a "Bad file descriptor" error. When I run the code from the command prompt it works fine. Help please!?
import subprocess
p = subprocess.call(['C:\Working\Python\celp.exe', '-o', 'ofile'], stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
In [84]: %run "C:\Working\Python\test.py"
Error: : Bad file descriptor
You forgot to add the stdout flag. add stdout = subprocess.PIPE, like this:
p = subprocess.call(
['C:\Working\Python\celp.exe', '-o', 'ofile'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, # needed for the next line to be sensible
stderr=subprocess.STDOUT,
)
now, try run your script again
Try this
import subprocess
p = subprocess.call(['C:\Working\Python\celp.exe', '-o', 'ofile'], stdin=subprocess.PIPE, stderr=subprocess.STDOUT, shell = True)