I am trying to figure out the best solution to accomplish this. Basically, I want to open another program from Python (doesn't matter, could be an image, executable, etc). I have tried os.system and subprocess.call however both will not terminate the script after, and will instead wait for a return. I have looked at os.execl, and it seems to close to what I need, but I am not sure if I understand the arg's as I always get exec format errors and invalid arguments. I am not even sure if this is the proper function for what I need. Any help would be appreciated.
I have tried using subprocess.call and subprocess.Popen using something similar to this:
import subprocess
subprocess.Popen("B:\test.txt")
and it ends up with the following error:
WindowsError: [Error 5] Access is denied.
Use subprocess.Popen[docs]
Just don't call communicate on the resulting object.
os.execlp("start", r"B:\test.txt")
(That's for Windows. On a Unix system running X11, you'd do this:)
os.execlp("xdg-open", r"B:\test.txt")
Related
I've been banging my head against the wall long enough, throwing in the towel here.
I am trying to use Python (specifically 3.8.2) to interface with a tool that has an ugly command line interface. I have the below command, which works. However, I've been reading up and it seems like this is a deprecated method, and they recommend using subprocess.run now. I've been trying convert my code over and having a lot of trouble, so hoping to find some help. Code below, along with an explanation.
os.system(rf'cmd /k "{ExecDrive}: & cd {ExecDirectory} & {command}"')
The first part of this is changing the drive letter and directory to a place where the programs executable is stored. Given a user could run this from any location, I have to ensure that they are in the right directory before running the command in the f-string below (which is essentially targetApp.exe -Arg1 Val1 -Arg2 Val2 etc.).
Second, I need to capture the output so I can parse it for some messages. I think I can figure that part out on my own if I can get the first part working, but if you're a subprocess.run pro, any help would be appreciated!
I was actually able to use the cwd command to accomplish what I needed. The new code is below.
subprocess.run(command, cwd=rf"{ExecDrive}:{ExecDirectory}", shell=True)
There is
subprocess.check_output(args)
for capturing output.
Reference: https://docs.python.org/3/library/subprocess.html#subprocess.check_output
I'm trying to incorporate the program TOPCAT (which has really amazing plotting capabilities) into a python script I have written. The problem is that when I make a call to the program it tells me:
OSError: [Errno 2] No such file or directory
Here's some background to the problem:
1) The way I usually open up topcat through the command line is through the alias I have created:
alias topcat='java -jar /home/username/topcat/topcat-full.jar'
2) If I'd like to open TOPCAT with a file in mind (let's use a csv file since that's what I'd like it to work with), I would type this into the command line:
topcat -f csv /home/username/path_to_csv_file/file.csv
And that also works just fine. The problem comes about when I try to call these commands while in my python script. I've tried both subprocess.call and os.system, and they don't seem to know of the existence of the topcat alias for some reason. Even doing a simple call like:
import subprocess
subprocess.call(['topcat'])
doesn't work... However, I can get topcat to open if I run this:
import subprocess
subprocess.call(['java','-jar','/home/username/topcat/topcat-full.jar'])
The problem with this is that it simply opens the program, and doesn't allow for me to tell it which file to take in and what type it happens to be.
Could somebody tell me what I'm doing incorrectly here? I've also looked into the shell=True option and it doesn't seem to be doing any better.
Okay - so I'm really excited that figured it out. What worked before was:
import subprocess
subprocess.call(['java','-jar','/home/username/topcat/topcat-full.jar'])
It turns out it can take more command line arguments. This is what eventually got it open up with the correct comma separated file through the command line:
import subprocess
subprocess.call(['java','-jar','/home/username/topcat/topcat-full.jar','-f','csv','/full/path/to/data.csv'])
Hopefully this is enough information to help other people who come across this specific task.
If anyone else comes across this, pystilts might be of interest.
https://github.com/njcuk9999/pystilts
edit: It is a native Python wrapper of Topcat/STILTS.
Trying to use Python for more than text parsing and figure the best way is to write a script I will find useful. I'm having an issue though I get an error when making the call.
from subprocess import call
call (["powercfg", "/batteryreport"])
The error I receive is the following:
An unexpected error condition has occurred. Unable to perform operation. You may not have permission to perform this operation.
I've run the command prompt under elevated user privileges as well with no dice. Any help would be appreciated.
Note: For those unfamiliar this command creates an HTML file of your battery use on Windows in your user directory (C:\Users\Name).
Perhaps you can use the full path to powercfg.exe?
Perhaps you can call([ ... ], shell=True)?
Perhaps you can check the return value of call()?
Caveat: new to Python.
Wanting to hear from professionals who actually use it:
What are the main differences between subprocess.Popen() and subprocess.call() and when is it best to use each one?
Unless you want to read why I was thinking about this question or what to center your answer around, you may stop reading now.
I was inspired to ask this question because I am working through an issue in a script where I started using subprocess.Popen(), eventually called a system pause, and then wanted to delete the .exe that created the system pause, but I noticed with Popen(), the commands all seemed to run together (the delete on the .exe gets executed before the exe is closed..), though I tried adding communicate().
Here is fake code for what I'm describing above:
subprocess.Popen(r'type pause.exe > c:\worker.exe', shell=True).communicate()
subprocess.Popen(r'c:\worker.exe', shell=True).communicate()
subprocess.Popen(r'del c:\worker.exe', shell=True).communicate()
subprocess.call(*popenargs, **kwargs)
Run command with arguments. Wait for
command to complete, then return the
returncode attribute.
If you create a Popen object, you must call the sp.wait() yourself.
If you use call, that's done for you.
running a python script from within ESRI's ArcMap and it calls another python script (or at least attempts to call it) using the subprocess module. However, the system window that it executes in (DOS window) comes up only very briefly and enough for me to see there is an error but goes away too quickly for me to actually read it and see what the error is!
Does anyone know of a way to "pause" the DOS window or possibly pipe the output of it to a file or something using python?
Here is my code that calls the script that pops up the DOS window and has the error in it:
py_path2="C:\Python25\python.exe"
py_script2="C:\DataDownload\PythonScripts\DownloadAdministrative.py"
subprocess.call([py_path2, py_script2])
Much appreciated!
Cheers
subprocess.call accepts the same arguments as Popen. See http://docs.python.org/library/subprocess.html
You are especially interested in argument stderr, I think. Perhaps something like that would help:
err = fopen('logfile', 'w')
subprocess.call([py_path2, py_script2], stderr=err)
err.close()
You could do more if you used Popen directly, without wrapping it around in call.
Try doing a raw_input() command at the end of your script (it's input() in Python 3).
This will pause the script and wait for keyboard input. If the script raises an exception, you will need to catch it and then issue the command.
Also, there are ways to read the stdout and stderr streams of your command, try looking at subprocess.Popen arguments at http://docs.python.org/library/subprocess.html.