I have a program that is supposed to create a text file. When called from subprocess.run() in python3, the program runs but it does not create the text file. The program works as expected when called from the terminal.
import subprocess as subp
...
comm=[os.getcwd()+'/test/myprogram.bin','arg1','arg2']
compl_proc = subp.run(comm,
capture_output=True,
text=True,
check=True)
The file was in the python script directory, because I never told subprocess.run() what is the current working directory of the subprocess. So cwd='...' is added.
import subprocess as subp
import os
...
comm=[os.getcwd()+'/test/myprogram.bin','arg1','arg2']
compl_proc = subp.run(comm,
cwd=os.getcwd()+'/test/',
capture_output=True,
text=True,
check=True)
Related
Suppose I run a .exe program within python whatever os or subprocess, the .exe program is designed to pop up some different results with different arguments, my steps are the following:
In python run .exe first(keep it alive, it will have communication
with hardware and do initialization)
send different arguments to
this .exe and collect the different outputs.
I tried the following code:
hello.py
import sys
for arg in sys.argv:
print(arg)
print("Hello World!")
test.py
import subprocess
command='./exe_example/output/hello/hello.exe a b'.split()
result = subprocess.run(command, stdout=subprocess.PIPE, text=True)
print(result.stdout)
the output is:
a b Hello World!
but how to change the input argv and get the result without running the whole .exe command again?
UPDATES:
I changed the hello.py as follows:
import sys
while True:
a = input()
print('response = ',a)
after compiling to .exe, I could manually run it in the dos window
hello.exe
a
response = a
b
response = b
c
response = c
but I still don't know how to run it in python
finally, I figured out, first from this post, I added flush()
cmd = "E:/exe_example/TestCl.exe"
p = Popen(cmd, stdin=PIPE,stdout=PIPE, bufsize=0)
p.stdin.write('getall\n'.encode())
p.stdin.flush()
for i in range(48):
print(p.stdout.readline())
then, very important, if I use read(), because the .exe is always listening to the input, so it will hang up forever and never output, in this case, readline() is very important
I want run Valgrind in a jail that created before and copyied required file in Jail. We know Valgrind generate two files XML and TXT files. I want to run python script that can cache the results of Valgrind files (XML and TXT file) and carry them to out of Jail. For example we have a function that run Valgrind in the Jail. Below code show it:
import os
def run_valgrind_in_jail(chroot_path, command):
os.chdir(chroot_path)
os.chroot(chroot_path)
return subprocess.run(['valgrind', '--xml=yes','--leak-check=full', '--verbose',
'--xml-file={}_valgrind.xml'.format(command),
'--log-file={}_valgrind.txt'.format(command),command],
stderr=subprocess.PIPE, stdout=subprocess.PIPE)
Valgrind generate two file XML and txt and I want to carry them to out of chroot (jail).
How can I get the output process of Valgrind and carry out to out of Jail.
You're putting your whole program in jail, not just the subprocess. Use a preexec_fn so only the subprocess is in the jail, not the rest of your Python program, and then you'll find your output files in the chroot_path directory:
import os, subprocess
class Jailer(object):
def __init__(self, chroot_path):
self.chroot_path = chroot_path
def __call__(self):
os.chdir(self.chroot_path)
os.chroot(self.chroot_path)
def run_valgrind_in_jail(chroot_path, command):
proc = subprocess.run(['valgrind', '--xml=yes','--leak-check=full', '--verbose',
f'--xml-file={command}_valgrind.xml',
f'--log-file={command}_valgrind.txt',
command],
stderr=subprocess.PIPE, stdout=subprocess.PIPE,
preexec_fn=Jailer(chroot_path))
xml_file = open(os.path.join(chroot_path, f'{command}_valgrind.xml'))
log_file = open(os.path.join(chroot_path, f'{command}_valgrind.txt'))
return (proc, xml_file, log_file)
Im trying to run a exe with some arguments within python using subprocesses Popen but the code is currently printing nothing as the output and a CMD window doesnt open when i run the file.
I know the command works as i manually paste it within CMD and it runs perfectly fine, what could i be doing wrong in my code?
import sys
import admin
import subprocess
from subprocess import Popen, PIPE
Path_2to3 = sys.executable[:-11] + "Scripts"
cmdCommand = '''cd "{}" && 2to3.exe -w "C:/Users/Desktop/bulk_converter/tests/test2.py"'''.format(Path_2to3)
process = subprocess.Popen(cmdCommand, stdout=subprocess.PIPE, shell=True)
output, error = process.communicate()
print(output, error)
retured values from print(output,error)
b'' None
Any help/suggestions would be appreciated.
Hi perhaps also specify stderr should be redirected to a pipe:
stderr=subprocess.PIPE
You may also be interested in passing a timeout parameter to communicate.
I'm attempting to create a python script to compile github surface kernel using their recommended steps.
https://github.com/dmhacker/arch-linux-surface
So far I'm stuck at a couple of sections.
Per the instructions for compiling the setup.sh must be run using sudo.
I've tried sending in the password before calling process using
preproc = subprocess.Popen(password, shell=True, stdout=subprocess.PIPE)
process = subprocess.Popen(["sudo", 'sh setup.sh'], shell=True, stdin=preproc.stdout, encoding='utf8')
I've tried sudo -S which doesn't seem to work at all. I've also tried lowercase -s.
I've tried changing subprocess.Popen to subprocess.call
password = getpass.getpass()
process = subprocess.Popen(["sudo", 'sh setup.sh'], shell=True,
stdin=subprocess.PIPE, encoding='utf8')
print(process.communicate(password + "\n"))
process.wait()
I expected the shell to be run at sudo level but it's not.
I'm not exactly sure what the difference is as I've since gone through many iterations, but finally got it to work and simplified. Hope this helps someone in the future.
import getpass
from subprocess import Popen, PIPE
password = getpass.getpass()
command = "./setup.sh"
process = Popen(['sudo', '-S', command], stdout=PIPE, encoding='utf8')
process.communicate(password)
How do I have it so that you pass in a python command to the exec() command, waits for completion, and print out the output of everything that just happened?
Many of the code out there uses StringIO, something that is not included in Python 3.5.
You can't. Exec just executes in place and returns nothing. Your best bet would be to write the command into a script and execute it with subprocess if you really want to catch all the output.
Here's an example for you:
#!/usr/bin/env python3
from sys import argv, executable
from tempfile import NamedTemporaryFile
from subprocess import check_output
with NamedTemporaryFile(mode='w') as file:
file.write('\n'.join(argv[1:]))
file.write('\n')
file.flush()
output = check_output([executable, file.name])
print('output from command: {}'.format(output))
And running it:
$ ./catchandrun.py 'print("hello world!")'
output from command: b'hello world!\n'
$