The right answer (using Python 2.7 and later, since check_output() was introduced then) is:
py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])
To demonstrate, here are my two programs:
py2.py:
import sys
print sys.argv
py3.py:
import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)
Running it:
$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"
Here's what's wrong with each of your versions:
py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
First, str('python py2.py') is exactly the same thing as 'python py2.py'—you're taking a str, and calling str to convert it to an str. This makes the code harder to read, longer, and even slower, without adding any benefit.
More seriously, python py2.py can't be a single argument, unless you're actually trying to run a program named, say, /usr/bin/python\ py2.py. Which you're not; you're trying to run, say, /usr/bin/python with first argument py2.py. So, you need to make them separate elements in the list.
Your second version fixes that, but you're missing the ' before test.txt'. This should give you a SyntaxError, probably saying EOL while scanning string literal.
Meanwhile, I'm not sure how you found documentation but couldn't find any examples with arguments. The very first example is:
>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'
That calls the "echo" command with an additional argument, "Hello World!".
Also:
-i is a positional argument for argparse, test.txt is what the -i is
I'm pretty sure -i is not a positional argument, but an optional argument. Otherwise, the second half of the sentence makes no sense.
The right answer (using Python 2.7 and later, since check_output() was introduced then) is:
py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])
To demonstrate, here are my two programs:
py2.py:
import sys
print sys.argv
py3.py:
import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)
Running it:
$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"
Here's what's wrong with each of your versions:
py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
First, str('python py2.py') is exactly the same thing as 'python py2.py'—you're taking a str, and calling str to convert it to an str. This makes the code harder to read, longer, and even slower, without adding any benefit.
More seriously, python py2.py can't be a single argument, unless you're actually trying to run a program named, say, /usr/bin/python\ py2.py. Which you're not; you're trying to run, say, /usr/bin/python with first argument py2.py. So, you need to make them separate elements in the list.
Your second version fixes that, but you're missing the ' before test.txt'. This should give you a SyntaxError, probably saying EOL while scanning string literal.
Meanwhile, I'm not sure how you found documentation but couldn't find any examples with arguments. The very first example is:
>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'
That calls the "echo" command with an additional argument, "Hello World!".
Also:
-i is a positional argument for argparse, test.txt is what the -i is
I'm pretty sure -i is not a positional argument, but an optional argument. Otherwise, the second half of the sentence makes no sense.
Since Python 3.5, subprocess.run is recommended instead of subprocess.check_output:
>>> subprocess.run(['cat','/tmp/text.txt'], check=True, stdout=subprocess.PIPE).stdout
b'First line\nSecond line\n'
Since Python 3.7, instead of the above, you can use capture_output=True parameter to capture stdout and stderr:
>>> subprocess.run(['cat','/tmp/text.txt'], check=True, capture_output=True).stdout
b'First line\nSecond line\n'
Also, you may want to use universal_newlines=True or its equivalent since Python 3.7 text=True to work with text instead of binary:
>>> stdout = subprocess.run(['cat', '/tmp/text.txt'], check=True, capture_output=True, text=True).stdout
>>> print(stdout)
First line
Second line
Printing output from subprocess.run
[Help] Getting blank string from subprocess.check_output
I remember having some similar issues. I checked my notes and I wound up doing it like this.
cmd = 'echo Some command string'
result = subprocess.run(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = result.stdout.decode('utf-8')
stderr = result.stderr.decode('utf-8')
status = 'COMPLETE' if result.returncode == 0 else 'FAILED' More on reddit.com Rhino8 python subprocess.check_output() error
subprocess.check_output(shell=True) handle non-zero exit status codes
Videos
I'm not getting an error but its not really printed what i wanted
I was trying to get these echo commands to show in either idle or running .py script
import subprocess allscripts = ["./scripty1", "./scripty2", "./scripty3", "./scripty4", "./scripty5"] for x in allscripts: subprocess.run([x], shell=True, capture_output=True) print(subprocess.check_output)
All it prints is this though
λ /bin/python /mnt/Stor2/Media/Share/DevShare/Py/InstallScript/InstallScript.py<function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040><function check_output at 0x7f7f2a94c040>
I posted about a day ago about this issue, but I have dug further since then. The issue is that I am trying to write a grader for student python code, so I execute their code by system command, and direct that output to a file. When I run the program from my IDE (PyCharm) it works perfectly. When I run it from the windows command line or from a batch file, I just get an empty string from the command running the student file.
I used to be using
os.system(f'python "{script_name}" > "{out_file}" 2>&1')
but have upgraded to using
f.write(subprocess.check_output(['python', script_name], stderr=subprocess.STDOUT, shell=True).decode('utf-8'))
I'm just getting an empty string when using subprocess.check_output and when using os.system a blank output file would be created every time. I have unit tested the issue using
print('test:', subprocess.check_output(['echo', 'test_phrase'], shell=True).decode('utf-8'))
which works fine from IDE, command line, or a batch file so long as shell=True is specified. Putting shell=True seems to have no effect on my actual use case.
I found someone else who seems to have my same problem, but they got no reply. I also found this similar issue on stack overflow, but it looks like their issue was something with activating the conda environment. I have tried the system 3.7 interpreter and my virtual env for the project, no difference. The folders I'm dealing with are just in my user directory and there should be no weird permission issues.
Any ideas on why I can't get any output unless I run from PyCharm would be great. The code is here and the issue is in run_file from FileExecution.execute.py if you care to look at the actual project.
I remember having some similar issues. I checked my notes and I wound up doing it like this.
cmd = 'echo Some command string'
result = subprocess.run(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = result.stdout.decode('utf-8')
stderr = result.stderr.decode('utf-8')
status = 'COMPLETE' if result.returncode == 0 else 'FAILED'
I'm just getting an empty string when using subprocess.check_output and when using os.system a blank output file would be created every time.
If you're redirecting the output and a blank file is being produced - this suggests the script does not produce any output.
If you run the same python script from the command line - what does it do?
I have unit tested the issue using
print('test:', subprocess.check_output(['echo', 'test_phrase'], shell=True).decode('utf-8'))
which works fine from IDE, command line, or a batch file so long as shell=True is specified.
This seems to be the opposite of what I see happening?
>>> subprocess.check_output(['echo', 'lol'], shell=True)
b'\n'
>>> subprocess.check_output(['echo', 'lol'])
b'lol\n'
You shouldn't need shell=True for what you're doing anyways.
Getting an empty string back suggests what ever you're running is not producing any output.
>>> subprocess.check_output(['python', '-c', '1 + 2'])
b''
>>> subprocess.check_output(['python', '-c', 'print(1 + 2)'])
b'3\n'
Working on a practice project that requires command line access over a client initiated ssh session. I have ssh working with paramiko. The client is able to log into the ssh server (code snippets below). When the client connects and the session is open, it sends 'Command Shell Open' via chan.send and goes into a while loop. chan.recv().decode() is used to receive commands from the server side across the ssh tunnel. subprocess.check_output(shell=True) is used to execute the command locally. The output of the command is then sent back to the server using chan.send(). This all works great for commands like ls,dir,pwd,ps ..etc. Commands that return a zero exit status during the subprocess.check_output(shell=True) step (I assume). When I issue a command that returns a non-zero exit status, ping for example I get this error message on the client and the client script stops.
File "/usr/lib/python3.8/subprocess.py", line 411, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/usr/lib/python3.8/subprocess.py", line 512, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command 'ping' returned non-zero exit status 127.
My question is how do I handle non-zero exit status using subprocess.check_output()
client.py snippet:
chan = client.get_transport().open_session()
chan.send('Command Shell Open')
while True:
command = chan.recv(1024).decode()
try:
CMD = subprocess.check_output(command, shell=True)
# CMD = subprocess.check_output(command, shell=True)
chan.send(CMD)
except subprocess.CalledProcessError as e:
chan.send(e)
client.close
server.py snippet:
try:
t = paramiko.Transport(client)
t.load_server_moduli()
t.add_server_key(host_key)
server = Server()
t.start_server(server=server)
chan = t.accept(20)
print(chan.recv(1024))
while True:
command= raw_input("SHELL >> ").strip('n')
chan.send(command)
print(chan.recv(1024) + 'n')