Popen returning nothing - python-3.x

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.

Related

how to repeatedly send argv inputs to an running .exe in python

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

Running a string command using exec with popen

I have a simple cmd_str containing a set of lines. Using exec, I can run those lines juts fine. However, running those lines in a separate process when shell=True is failing. Is this dues to missing quotes? what is happening under the hood?
import subprocess
cmd_str = """
import sys
for r in range(10):
print('rob')
"""
exec(cmd_str) # works ok
full_cmd = f'python3 -c "exec( "{cmd_str}" )"'
process = subprocess.Popen([full_cmd],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(output, error) = process.communicate()
exit_code = process.wait()
output_msg = output.decode("utf-8", 'ignore')
error_msg = error.decode("utf-8", 'ignore').strip()
Your approach is slightly inaccurate. I believe the problem you're having has to do with the subprocess usage. The first thing you must realise is that exec
is a way to send and execute python code to and from the interpreter directly. This is why it works inside python programs(and it is generally not a good approach). Subprocesses on the other hand handle command like they are being called directly from the terminal or shell. This means that you no longer need to include exec cause you are already interacting with the python interpreter when you call python -c.
To get this to run in a subprocess environment all you need to do is
full_cmd = f'python3 -c "{cmd_str}"'
process = subprocess.Popen(full_cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Also, notice the absence of square brackets when calling subprocess.Popen, this is because that particular approach works slightly different and if you want to use the square brackets your command will have to be
full_cmd = ['python3', '-c', f'{cmd_str}']
process = subprocess.Popen(full_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
And with these few changes, everything should work OK

Unable to get send sudo password to subprocess.Popen() successfully in Python for bash

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)

Can i access the variables of the python script after run that python script with console?

I run the python script using terminal command
python3 myScript.py
It's simply run my program but if i want to open python console after complete run of my script so that i can access my script's variables.
So, What should i do ? and How can i get my script's variables after run the code using terminal ?
Open a python terminal (type 'python' in cmd);
Paste this (replace 'myScript.py' with your script filename):
def run():
t = ""
with open('myScript.py') as f:
t = f.read()
return t
Type exec(run()). Now you will have access to the variables defined in myScript.py.
I needed to do this so I could explore the result of a request from the requests library, without having to paste the code to make the requests every time.
Make the program run the other program you want with the variables as arguments. For example:
#program1
var1=7
var2="hi"
import os
os.system("python %s %d %s" % (filename, var1, var2))
#program2
import sys
#do something such as:
print(sys.argv[1]) #for var1
print(sys.argv[2]) #for var2
Basically, you are running program2 with arguments that can be referenced later.
Hope this helps :)

How do I print the output of the exec() function in python 3.5?

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'
$

Resources