I read about the subprocess module and I found out that it is possible to send data-file (txt) into application that has been called through the subprocess module in python like:
import subprocess
f = open('data-file.txt', 'r')
with subprocess.Popen('runsoftware.exe', stdout=subprocess.PIPE,
stdin=f)as p:
stdout, stderr = p.communicate()
sleep(1)
subprocess.Popen.kill(p)
but nothing happens. Is there any better way of sending data-file into an application?
You a erasing the file via opening in write mode.
import subprocess
f = open('data-file.txt', 'r')
with subprocess.Popen('runsoftware.exe', stdout=subprocess.PIPE,
stdin=f)as p:
stdout, stderr = p.communicate()
sleep(1)
subprocess.Popen.kill(p)
Should send a file. Also you should close the file at the end or your code.
Related
I'm trying to read the content of a file with python 3.8.5 but the output is empty, I don't understand what I'm doing wrong.
Here is the code:
import subprocess
import os
filename = "ls.out"
ls_command = "ls -la"
file = open(filename, "w")
subprocess.Popen(ls_command, stdout=file, shell=True)
file.close()
# So far, all is ok. The file "ls.out" is correctly created and filled with the output of "ls -la" command"
file = open(filename, "r")
for line in file:
print(line)
file.close()
The output of this script is empty, it doesn't print anything. I'm not able to see the content of ls.out.
What is not correct here ?
Popen creates a new process and launches it but returns immediately. So the end result is that you've forked your code and have both processes running at once. Your python code in executing faster than the start and finish of ls. Thus, you need to wait for the process to finish by adding a call to wait():
import subprocess
import os
filename = "ls.out"
ls_command = "ls -la"
file = open(filename, "w")
proc = subprocess.Popen(ls_command, stdout=file, shell=True)
proc.wait()
file.close()
file = open(filename, "r")
for line in file:
print(line)
file.close()
Popen merely starts the subprocess. Chances are the file is not yet populated when you open it.
If you want to wait for the Popen object to finish, you have to call its wait method, etc; but a much better and simpler solution is to use subprocess.check_call() or one of the other higher-level wrappers.
If the command prints to standard output, why don't you read it drectly?
import subprocess
import shlex
result = subprocess.run(
shlex.split(ls_command), # avoid shell=True
check=True, text=True, capture_output=True)
line = result.stdout
I'm creating a text file, and immediately after calling a subprocess that does some computation based on the text file.
When I call the subprocess by itself, it's able to read from the file as expected, but when I try to create a file and write to it immediately before, it is not able to read from the file.
f = open('name_data.txt', 'w')
f.write(name)
f.close()
cmd = ['g2p-seq2seq', '--decode', 'name_data.txt', '--model', 'g2p-seq2seq-cmudict']
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
process.wait()
#etc....
import subprocess
open("Edited.py", "w").write("Thing To Write")
A = subprocess.Popen('Command you want to call', shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
print(A.communicate())
Here's my code to execute a jar file in Python:
import os
os.system("java -jar xyz.jar")
I can see the output on terminal, but want to store it in a file. How can I do that?
With subprocess.call you can pipe outputs (stdout, stderr or both) directly into file:
import subprocess
subprocess.call("java -jar xyz.jar", shell=True, stdout=open('outfile.txt', 'wt'), stderr=subprocess.STDOUT)
Note that I added shell=True parameter, which is required if your application requires shell-specific variables (such as where Java is located).
Also note that in the above call, the output streams are handled as follows:
stderr stream is piped to stdout, and
stdout is piped to outfile
More details on stream configurations are available in subprocess manual page.
Don't use os.system, use subprocess instead.
import subprocess
output = subprocess.check_output(["java", "-jar", "xyz.jar"])
file = open('file.txt', 'w+')
file.write(output)
file.close()
I use external library, like this:
from some_lib import runThatProgram
infile = '/tmp/test'
outfile = '/tmp/testout'
runThatProgram(infile, outfile)
while runThatProgram is:
def runThatProgram(infile, outfile):
os.system("%s %s > %s" % ('thatProgram', infile, outfile))
The problem is that 'thatProgram' returns lots of stuff on STDERR, I want to redirect it to a file, but I cannot edit runThatProgram code because it is in third party lib!
To illustrate what Rosh Oxymoron said, you can hack the code like this :
from some_lib import runThatProgram
infile = '/tmp/test'
outfile = '/tmp/testout 2>&1'
runThatProgram(infile, outfile)
with this, it will call
thatProgram /tmp/test > /tmp/testout 2>&1
that will redirected stderr (2) to stdout (1), and everything will be logged in your outfile.
To elaborate on using subprocess, you can open it, give it a pipe and then work from there so
import subprocess
program = "runthatprogram.py".split()
process = subprocess.Popen(program, stdout = subprocess.PIPE, stderr = open('stderr','w')) #stderr to fileobj
process.communicate()[0] #display stdout
I am using subprocess module, which Popen class output some results like:
063.245.209.093.00080-128.192.076.180.01039:HTTP/1.1 302 Found
063.245.209.093.00080-128.192.076.180.01040:HTTP/1.1 302 Found
and here is the script I wrote:
import subprocess, shlex, fileinput,filecmp
proc = subprocess.Popen('egrep \'^HTTP/\' *', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,)
stdout_value = proc.communicate()[0]
print 'results:'
print stdout_value
My question is: how to convert/record the results from stdout into a file?
I appreciate all your responses and helps!
import subprocess
import glob
def egrep(pattern, *files):
""" runs egrep on the files and returns the entire result as a string """
cmd = ['egrep', pattern]
for filespec in files:
cmd.extend(glob.glob(filespec))
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
return proc.communicate()[0]
results = egrep(r'^HTTP/', '*')
print 'results:'
print results
# write to file
with open('result_file.txt', 'w') as f:
f.write(results)
One or any of the stdin, stdout, and stderr arguments to subprocess.Popen() can be file objects (or a file descriptor), which will cause the program to read from or write to the given files.