I am trying to execute commands in the python interactive shell and print the output through popen.
I started with this code:
import subprocess
if __name__ == "__main__":
process = subprocess.Popen('python',
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=True)
process.stdin.write('help()\n'.encode())
process.stdin.flush()
output = process.stdout.read()
print(output)
process.stdin.write('q\n'.encode())
process.stdin.flush()
output = process.stdout.read()
print(output)
process.stdin.write('exit()\n'.encode())
process.stdin.flush()
output = process.stdout.read()
print(output)
However the execution is blocked at line process.stdout.read().
What am i doing wrong here?
Python 3 documentation says
read(size=-1)
Read and return up to size bytes. If the argument is omitted, None, or negative,
data is read and returned until EOF is reached. An empty bytes object is returned
if the stream is already at EOF.
Your read() is a blocking call, try reading with a size or try using peek to determine if there is content in the buffer before reading.
Related
In case some command we try to execute is not found on the server or a specific error from a command output.
For example:
#!/usr/bin/env python3
import subprocess
os_cmd = 'ech hello'
subprocess.Popen(os_cmd, shell=True)
Error output is:
/bin/sh: 1: ech: not found
How to write exception specific for such command not found error instead of such Built-in Exceptions or instead of just checking only the return code zero or non-zero?
Or is the only way to do it in a dirty way as follows?
#!/usr/bin/env python3
import subprocess
os_cmd = 'ech hello'
p1 = subprocess.Popen(os_cmd, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = p1.communicate()
exit_code = p1.poll()
if exit_code != 0:
string = stderr.decode()
substring = "not found"
if substring in string:
print("It is command not found error")
print("Do some solution...")
else:
print("Command succeeded")
out = stdout.decode().strip().split()[0]
print(out)
Output:
It is command not found error
Do some solution...
I am trying to print output using sys.stdout but getting none on stdout. please check
# Read input from STDIN. Print output to STDOUT
import math
import os
import random
import re
import sys
def stdin(s):
if (len(s)>=2 and len(s)<=10000):
ev=[s[i] for i in range(len(s)) if i%2==0]
od=[s[i] for i in range(len(s)) if i%2!=0]
even=''.join(map(str,ev))
odd=''.join(map(str,od))
sys.stdout.write("{0} {1}".format(even,odd)) #print outpout using stdout but error got
sys.stdout.flush()
if __name__ == '__main__':
s = input().strip()
stdin(s)
By default python uses stdout when using the built in print() function. It will also read from stdin when using input(). I would suggest going that route as it will be less prone to error. Otherwise could you share the exact error message you are getting? The code is running without error for me.
Using the following code:
import subprocess
while(1==1):
command_terminal= input('Enter the command you would like to pass: ')
command_terminal=command_terminal.split()
result=subprocess.run(command_terminal, stdout=subprocess.PIPE)
result=result.stdout.decode('utf-8')
print(result)
Basically I am trying to emulate terminal as a whole. But I am sort of failing.
Stuff like ps -A Doesn't give an output at all. Any help..?
Use subprocess.check_output. The encoding argument convert the output bytes to str.
import subprocess
while (1 == 1):
command_terminal = input('Enter the command you would like to pass: ')
command_terminal = command_terminal.split()
result = subprocess.check_output(command_terminal, encoding='utf-8')
print(result)
Note that CalledProcessError is raise if the exit code is not zero.
Alternatively, subprocess.run with capture_output=True may be used. The output is stored in the returned CompletedProcess.stdout and no exception whatever the exit code is.
import subprocess
while (1 == 1):
command_terminal = input('Enter the command you would like to pass: ')
command_terminal = command_terminal.split()
completed = subprocess.run(command_terminal, encoding='utf-8', capture_output=True)
result = completed.stdout
print(result)
I actually did what you did and hosted it over on github (https://github.com/Pythers/PyCMD/blob/master/main.py)
I believe your problem is that you need to set the stdout to the normal instead of subprocess.PIPE
import sys
import subprocess
while 1==1:
command_terminal= input('Enter the command you would like to pass: ')
command_terminal=command_terminal.split()
result=subprocess.run(command_terminal, stdout=sys.stdout)
A terminal command that we type in the terminal might print some output on the terminal. When we use this command in a python script and call a system call say:
os.system('ls')
we do obtain the output, but somehow it returns an integer to indicate a successful execution of the process:
>>> x = os.system('ls') #prints some output
>>> x
>>> 0
I need a function that stores the output in x as a string that I need to parse. What is the python function that does this?
You would use the subprocess module.
from subprocess import PIPE, Popen
proc = Popen(["ls"], stdout=PIPE)
stdout, stderr = proc.communicate()
Or if you're using Python 3.5 or greater, then run is recommended.
import subprocess
completed = subprocess.run(["ls", "-l"], stdout=subprocess.PIPE, encoding="utf-8")
#output is stored in completed.stdout
I want to capture all output into variables that subprocess prints out. Here is my code:
#!/usr/bin/env python3
import subprocess # Subprocess management
import sys # System-specific parameters and functions
try:
args = ["svn", "info", "/directory/that/does/not/exist"]
output = subprocess.check_output(args).decode("utf-8")
except subprocess.CalledProcessError as e:
error = "CalledProcessError: %s" % str(e)
except:
error = "except: %s" % str(sys.exc_info()[1])
else:
pass
This script still prints this into the terminal:
svn: E155007: '/directory/that/does/not/exist' is not a working copy
How can I capture this into a variable?
check_output only captures stdout and NOT stderr (according to https://docs.python.org/3.6/library/subprocess.html#subprocess.check_output )
In order to capture stderr you should use
>>> subprocess.check_output(
... "ls non_existent_file; exit 0",
... stderr=subprocess.STDOUT, ...)
I recommend reading the docs prior to asking here by the way.