I want to redirect the output of my jar in a file with python I have tried the following but it didn't work out
import sys
import subprocess
cmdargs = sys.argv
fname = str(cmdargs[1])
input = '../res/test/'+fname
output = '../res/res/'+fname
subprocess.Popen(['java', '-jar', '../res/chemTagger2.jar',input,'>',output])
the output is print in the console
You can redirect the subprocess.Popen stdout and stderr by using their parameters within the Popen command, as follows:
import sys
import subprocess
cmdargs = sys.argv
fname = str(cmdargs[1])
input = '../res/test/' + fname
output = '../res/res/' + fname
with open(output, 'a') as f_output:
subprocess.Popen(['java', '-jar', '../res/chemTagger2.jar',input], stdout=f_output)
Related
I want to open a script with popen, with a sysargv argument like this:
import subprocess
Script = '/home/Network_Monitor_Device/Scripts/Traceroute.py 192.168.76.1'
p = subprocess.Popen(['python','-u',Script], stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
out = p.stdout.readline()
print out
Traceroute.py
import os
import sys
import subprocess
subprocess.check_output("traceroute " + str(sys.argv[1]), shell=True)
I'm getting this error:
python: can't open file
'/home/Network_Monitor_Device/Scripts/Traceroute.py 192.168.76.1':
[Errno 2] No such file or directory
It's expecting a list. Try:
p = subprocess.Popen(['python','-u', '/home/Network_Monitor_Device/Scripts/Traceroute.py', '192.168.76.1'], stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
I have below code :
import os, subprocess
def cfile():
p = r'/mypath/abc'
cmd = ["who am i | awk '{print $1}'"]
if not os.path.exists(p):
fh = open(p, 'a')
try:
subprocess.Popen(cmd, stdout=fh)
finally:
fh.close()
cfile()
above code is creating the file called 'folder' but not writing anything. Can you please help me to get to know what is wrong here. I am using python 2.7
You could call .wait() on each Popen object in order to be sure that it's finished and then call flush(). Maybe something like this:
import os
import subprocess
def cfile():
p = r'/mypath/abc'
cmd = ["who am i | awk '{print $1}'"]
fh = open(p, 'a+')
try:
sb = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=fh)
sb.wait()
fh.flush()
finally:
fh.close()
cfile()
I have the following shell script that I would like to write in Python (of course grep . is actually a much more complex command):
#!/bin/bash
(cat somefile 2>/dev/null || (echo 'somefile not found'; cat logfile)) \
| grep .
I tried this (which lacks an equivalent to cat logfile anyway):
#!/usr/bin/env python
import StringIO
import subprocess
try:
myfile = open('somefile')
except:
myfile = StringIO.StringIO('somefile not found')
subprocess.call(['grep', '.'], stdin = myfile)
But I get the error AttributeError: StringIO instance has no attribute 'fileno'.
I know I should use subprocess.communicate() instead of StringIO to send strings to the grep process, but I don't know how to mix both strings and files.
p = subprocess.Popen(['grep', '...'], stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
output, output_err = p.communicate(myfile.read())
Don't use bare except, it may catch too much. In Python 3:
#!/usr/bin/env python3
from subprocess import check_output
try:
file = open('somefile', 'rb', 0)
except FileNotFoundError:
output = check_output(cmd, input=b'somefile not found')
else:
with file:
output = check_output(cmd, stdin=file)
It works for large files (the file is redirected at the file descriptor level -- no need to load it into the memory).
If you have a file-like object (without a real .fileno()); you could write to the pipe directly using .write() method:
#!/usr/bin/env python3
import io
from shutil import copyfileobj
from subprocess import Popen, PIPE
from threading import Thread
try:
file = open('somefile', 'rb', 0)
except FileNotFoundError:
file = io.BytesIO(b'somefile not found')
def write_input(source, sink):
with source, sink:
copyfileobj(source, sink)
cmd = ['grep', 'o']
with Popen(cmd, stdin=PIPE, stdout=PIPE) as process:
Thread(target=write_input, args=(file, process.stdin), daemon=True).start()
output = process.stdout.read()
The following answer uses shutil as well --which is quite efficient--,
but avoids a running a separate thread, which in turn never ends and goes zombie when the stdin ends (as with the answer from #jfs)
import os
import subprocess
import io
from shutil import copyfileobj
file_exist = os.path.isfile(file)
with open(file) if file_exists else io.StringIO("Some text here ...\n") as string_io:
with subprocess.Popen("cat", stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) as process:
copyfileobj(string_io, process.stdin)
# the subsequent code is not executed until copyfileobj ends,
# ... but the subprocess is effectively using the input.
process.stdin.close() # close or otherwise won't end
# Do some online processing to process.stdout, for example...
for line in process.stdout:
print(line) # do something
Alternatively to close and parsing, if the output is known to fit in memory:
...
stdout_text , stderr_text = process.communicate()
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.