Export command line output to a file in Python - python

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()

Related

How to send data file into an application through python

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.

Unable to read file with python

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

Redirecting stdout to Terminal AND a log .txt file with Python Subprocess.run()

I am trying to run a command and redirect the output to a .txt file as well as be able to see it in terminal using subprocess.run(). I previously used 2>&1 | file.txt to accomplish this but would like to mimic that flavor with subprocess.run() and shell = False
I am currently able to redirect stdout to a .txt. successfully but I would like to be able to see it in terminal as well. Is there a way to accomplish this? I am on Python 3.6
with open(model_dest_dir + 'Deepspeech_progress.txt', 'w') as f:
train_model = subprocess.run(train_cmds, shell = False, cwd = '/home/', env = export_dict, stdout = f)
#for stdout_line in iter(train_model.stdout.readline, b''):
# print(stdout_line)
f.close()
Looks like I have a working solution albeit not with subprocess.run(). I had to use Popen like so:
# train the model and write logs to .txt file
with open(model_dest_dir + 'Deepspeech_progress.txt', 'w') as f:
train_model_proc = subprocess.Popen(train_cmds, cwd = '//DeepSpeech/', env = export_dict, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, universal_newlines = True)
for line in train_model_proc.stdout:
sys.stdout.write(line)
f.write(line)
train_model_proc.wait() # wait for Popen to finish
f.close()

Writing to a file and reading it from a subprocess in python?

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())

How to redirect stderr of a program that is run using os.system by a third-party python library

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

Categories

Resources