- How do I pipe a subprocess call to a text file?
- 2 Answers 2
- How can I open another Python file using Python Subprocess? [duplicate]
- 2 Answers 2
- opening a file as a subprocess
- 3 Answers 3
- How can I open files in external programs in Python? [duplicate]
- 3 Answers 3
- Opening a file with subprocess.call .
- Launching with multiple arguments
How do I pipe a subprocess call to a text file?
RIght now I have a script that I run. When I run it and it hits this line, it starts printing stuff because run.sh has prints in it. How do I pipe this to a text file also? (And also print, if possible)
2 Answers 2
If you want to write the output to a file you can use the stdout-argument of subprocess.call .
- None (the default, stdout is inherited from the parent (your script))
- subprocess.PIPE (allows you to pipe from one command/process to another)
- a file object or a file descriptor (what you want, to have the output written to a file)
You need to open a file with something like open and pass the object or file descriptor integer to call :
f = open("blah.txt", "w") subprocess.call(["/home/myuser/run.sh", "/tmp/ad_xml", "/tmp/video_xml"], stdout=f)
I’m guessing any valid file-like object would work, like a socket (gasp :)), but I’ve never tried.
As marcog mentions in the comments you might want to redirect stderr as well, you can redirect this to the same location as stdout with stderr=subprocess.STDOUT . Any of the above mentioned values works as well, you can redirect to different places.
@Goldname you need a shell to do redirection, so: subprocess.call([«echo», «1», «>>», «t.txt»], shell=True) should work.
@WesMason Thanks, but i thought subprocess.call worked in a way that was basically like copying and pasting into the shell?
@Goldname nah, everything in subprocess relies on the underlying Popen class, which opens an process, shell=True will force the process to be executed in the system default shell (e.g. /bin/sh on POSIX systems, which is usually bash or dash), it’s more secure that way as you’re not open to all of the extra functionality provided by the shell (a whole programming language unto itself, with it’s own exploits if passing in user provided data). Also take a look at shlex.quote if you are passing any possibly dirty data to a subshell.
Should we also close the file after we are done? this will close the file after we are done: with open(«blah.txt»,»w») as f: subprocess.call([«/home/myuser/run.sh», «/tmp/ad_xml», «/tmp/video_xml»], stdout=f) @Skurmedel
How can I open another Python file using Python Subprocess? [duplicate]
I have a Python file, which I want to open, keep open for 5 seconds, and then close it, and then repeat. I am using Python Subprocess for this, using the following code:
import subprocess import time import sys p = subprocess.Popen("pagekite.py") time.sleep(4) p.terminate()
Traceback (most recent call last): File "C:/Users/ozark/Desktop/Savir/Programming/Choonka/closetry.py", line 5, in p = subprocess.Popen("pagekite.py") File "C:\Users\ozark\AppData\Local\Programs\Python\Python38-32\lib\subprocess.py", line 854, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "C:\Users\ozark\AppData\Local\Programs\Python\Python38-32\lib\subprocess.py", line 1307, in _execute_child hp, ht, pid, tid = _winapi.CreateProcess(executable, args, OSError: [WinError 193] %1 is not a valid Win32 application
It seems only executables can be opened using this method? Then how do I do the same thing for a Python file? Any help will be appreciated. Thanks in advance. MODIFICATIONS: I am now using subprocess.call(‘start pagekite.py’, shell=True). How do I terminate this? Thanks.
You’d need to run the python interpreter, and give your script as an argument. As the error says, you can’t directly run a Python script. Are you sure what you’re trying to do can’t be achieved through just importing the other script though?
If Python cannot import the script, are you sure it can execute it? Fixing it so you can import it is usually the best solution.
Yes, the script (a third party Python file) can be executed, but only by double-clicking the file, importing doesn’t work.
Windows can be configured to supply python before the script name when you try to execute it, but this is less commonly done than on Unix-like platforms; the simple and portable solution is to spell out python .
2 Answers 2
I had this question myself! It’s actually much easier than it seems! You need some modules for this though, and there will be some wait time to start the Python file, but it works great as an automated process.
You don’t actually need Psutil for something simple like this. Refer to the following code, and you’ll figure something or the other out:
import subprocess import time import sys import os while True: subprocess.call('start pagekite.py', shell=True) time.sleep(32) os.system("TASKKILL /F /IM py.exe")
Basically, Python scripts actually run through C:\WINDOWS\py.exe, and if you’re able to close py.exe, you should be good! For this, just close py.exe using os.system(«TASKKILL /F /IM py.exe»)
Using a while loop, you can run the code forever, thus opening «pagekite.py», keeping it open for at least 20 seconds (I figured this would be the load time for such a script — 5 seconds isn’t enough), and then closing «py.exe», which would in turn close «pagekite.py». Afterwards, the whole thing occurs again.
You could change the «32» back to «5», but «pagekite.py» probably won’t have enough time to load, so I would keep it at «32», unless your server manages a lot of traffic.
I hope this helps you, and happy coding!
opening a file as a subprocess
i am just trying to do the basic opening of the file while monitoring whether it’s still opened or not, but it just opens it and exits. any suggestions to why that happens?
class Opener: def __init__(self, file_path): self.file_path = file_path self.process = None def start(self): sub = subprocess.Popen(self.file_path, shell=True) while sub.poll(): pass print "closed" new = Opener("test.jpg") t1 = threading.Thread(target=new.start) t1.start()
I used the shell argument which runs the parameter like it would on the command line, it opens the picture like it should but it would wait until it is closed
3 Answers 3
This only works on Windows with shell=True because the default program for the extension is used to open the given file, it’s the equivalent of using cmd /c Path\To\File
does not what you want. sub.poll() returns None while the program is running, and the exit code of the program when it has finished. If the program were to terminate with an exit code other then 0 before reaching this loop, then it would just keep looping and consuming CPU. If the program is still running or has completed successfully then the loop is not entered at all.
Checking wheather a process is still runing using poll() should be done by checking sub.poll() is None , or better use sub.wait() .
Some programs however allow only one active instance, if you try to start a second instance it will instead open the file in the open window and exit immediately. In that case there is no easy way to know wheather the file is still open in the application. So the behaviour also depends on the registered program.
How can I open files in external programs in Python? [duplicate]
I’m wondering how to open files in programs such as Notepad and Picture Viewer depending on the extension the file has. I’m using Python 3.3 on Windows. I’ve done some research and people have mentioned a module named Image , but when I try and import this module I get an ImportError. Here’s what I have so far:
def openFile(): fileName = listbox_1.get(ACTIVE) if fileName.endswith(".jpg"): fileName.open()
3 Answers 3
On Windows you could use os.startfile() to open a file using default application:
import os os.startfile(filename)
There is no shutil.open() that would do it cross-platform. The close approximation is webbrowser.open() :
import webbrowser webbrowser.open(filename)
that might use automatically open command on OS X, os.startfile() on Windows, xdg-open or similar on Linux.
If you want to run a specific application then you could use subprocess module e.g., Popen() allows to start a program without waiting for it to complete:
import subprocess p = subprocess.Popen(["notepad.exe", fileName]) # . do other things while notepad is running returncode = p.wait() # wait for notepad to exit
There are many ways to use the subprocess module to run programs e.g., subprocess.check_call(command) blocks until the command finishes and raises an exception if the command finishes with a nonzero exit code.
only problem is that json files don’t have a default application so that box would appear asking the user what program to open it in
@ToothpickAnemone: yes, there is no os.startfile on Linux. Follow the link to os.startfile() docs in the answer (it says that the function is available only on Windows)
Use this to open any file with the default program:
import os def openFile(): fileName = listbox_1.get(ACTIVE) os.system("start " + fileName)
If you really want to use a certain program, such as notepad, you can do it like this:
import os def openFile(): fileName = listbox_1.get(ACTIVE) os.system("notepad.exe " + fileName)
Also if you need some if checks before opening the file, feel free to add them. This only shows you how to open the file.
os.system() will block the calling thread. Something out of the subprocess module might be more appropriate.
I thin ill need to add the program name because files such as json that don’t have a specific program to open will cause problems
@LWH91 I’d recommend adding a check if the file ends with .json , if it does, open the file with a custom program. Else use «start».
Expanding on FatalError’s suggestion with an example.
One additional benefit of using subprocessing rather than os.system is that it uses the same syntax cross-platform ( os.system on Windows requires a «start» at the beginning, whereas OS X requires an «open». Not a huge deal, but one less thing to remember).
Opening a file with subprocess.call .
All you need to do to launch a program is call subprocess.call() and pass in a list of arguments where the first is the path to the program, and the rest are additional arguments that you want to supply to the program you’re launching.
For instance, to launch Notepad.exe
import subprocess path_to_notepad = 'C:\\Windows\\System32\\notepad.exe' path_to_file = 'C:\\Users\\Desktop\\hello.txt' subprocess.call([path_to_notepad, path_to_file])
Passing multiple arguments and paths is equally as simple. Just add additional items to the list.
Launching with multiple arguments
This, for example, launches a JAR file using a specific copy of the Java runtime environment.
import subprocess import os current_path = os.getcwd() subprocess.call([current_path + '/contents/home/bin/java', # Param 1 '-jar', #Param2 current_path + '/Whoo.jar']) #param3
Argument 1 targets the program I want to launch. Argument2 supplies an argument to that program telling it that it’s going to run a JAR, and finally Argument3 tells the target program where to find the file to open.