Im trying to use ubuntu terminal through python script.
The script receives the command text(from input() for test), sends it to the terminal, the terminal return the result of the command, script print result in a console.
I already get that I should use subprocess Popen and PIPE, but after inputing 1st command, script print only b'', after 2nd raise error "ValueError: Cannot send input after starting communication"
my test code(yes, its bad):
import subprocess as sb
from subprocess import PIPE, Popen
p=Popen(['gnome-terminal'],stdout=PIPE,stdin=PIPE,stderr=PIPE)
command = 'cmd'
while True:
command = input()
out_data, err_data = p.communicate(command.encode())
print(repr(out_data))
I know I do it in a wrong way, but can't find right. Sorry for English.Thanks.
You can do this using the os module:
#!/usr/bin/env python
import os
output = os.listdir('path_to_folder') # output is a list
# Do whatever you want to output
You can read more about what else the os module can do at https://docs.python.org/3/library/os.html. Note that the methods in the module are portable across different OSes, so you can in fact use your script outside Ubuntu.
Related
I am trying to write the codes to run a C executable using Python.
The C program can be run in the terminal just by calling ./myprogram and it will prompt a selection menu, as shown below:
1. Login
2. Register
Now, using Python and subprocess, I write the following codes:
import subprocess
subprocess.run(["./myprogram"])
The Python program runs but it shows nothing (No errors too!). Any ideas why it is happening?
When I tried:
import subprocess
subprocess.run(["ls"])
All the files in that particular directory are showing. So I assume this is right.
You have to open the subprocess like this:
import subprocess
cmd = subprocess.Popen(['./myprogram'], stdin=subprocess.PIPE)
This means that cmd will have a .stdin you can write to; print by default sends output to your Python script's stdout, which has no connection with the subprocess' stdin. So do that:
cmd.stdin.write('1\n') # tell myprogram to select 1
and then quite probably you should:
cmd.stdin.flush() # don't let your input stay in in-memory-buffers
or
cmd.stdin.close() # if you're done with writing to the subprocess.
PS If your Python script is a long-running process on a *nix system and you notice your subprocess has ended but is still displayed as a Z (zombie) process, please check that answer.
Maybe flush stdout?
print("", flush=True,end="")
I have been trying to write a function which would execute a command passed to it thru a parameter using POPEN along with Context Managers. Unfortunately, I am unable to get it to work. Can someone please help?
import os
import sys
import subprocess
import inspect
def run_process(cmd_args):
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE) as proc:
log.write(proc.stdout.read())
run_process("print('Hello')")
The output expected is "Hello". Can someone please point out where I am going wrong?
What you have done is right if you are running a bash command through the subprocess.
Inside the context manager "with ..." what you have done is to reading out the output from the terminal and storing them as byte(s) in "output" variable and trying to print out the bytes in ASCII after decoding it.
Try returning the value from the context manager and then decode it in the calling function:
import os
import sys
import subprocess
import inspect
def run_process(cmd_args): # Below added shell=True' in parameters.
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=True) as proc:
return proc.stdout.read() # returns the output
# Optionally you can use the 'encoding='utf-8' argument
# instead and just print(proc.stdout.read()).
print(run_process().decode('utf-8'))
I was having a similar issue while pipelining a process to another program and I did the decoding in the other program and surprisingly it worked. Hope it works for you as well.
def run_process(cmd_args):
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE) as p:
output = p.stdout.read()
return output
It worked for the same question.
Popen runs the command it receives as you would run something in your terminal (example: CMD on Windows or bash on Linux). So, it does not execute Python, but Bash code (on Linux for ex). The Python binary has a command, -c that does what you would need: executes a Python command right away. So you have to options:
either use echo Hello (works on Windows or Linux too, echo it's both
in batch and in bash)
or you could use python -c "print('Hello') instead of just the print command.
Without making too many changes to your existing script, I have edited your script with the below comments indicating what I did to get it to work. I hope this helps.
import os
import sys
import subprocess
import inspect
def run_process(cmd_args): # Below added shell=True' in parameters.
with subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=True) as proc:
output = proc.stdout.read() # Reads the output from the process in bytes.
print(output.decode('utf-8')) # Converts bytes to UTF-8 format for readability.
# Optionally you can use the 'encoding='utf-8' argument
# instead and just print(proc.stdout.read()).
run_process("echo Hello") # To display the message in the prompt use 'echo' in your string like this.
Note: Read the Security Considerations section before using shell=True.
https://docs.python.org/3/library/subprocess.html#security-considerations
I have a c executable which gets data from a iot hardware and print information on console using printf. I want to run this executable from python which I am able to do so using subprocess.call in following way
subprocess.call(["demoProgram", "poll"])
and print the output to console. But I need to capture this output(printf) using my python code to process information further in real time. How can I capture this output using subprocess in real time?
The following opens a subprocess and creates an iterator from the output.
import subprocess
import sys
proc = subprocess.Popen(['ping','google.com'], stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ''):
print(line) # process line-by-line
This solution was modified from the answer to a similar question.
if you're using python 2x
have a look at the commands module
import commands
output=commands.getoutput("gcc demoProgram.c") #command to be executed
print output
for python3x
use the subprocess module
import subprocess
output=subprocess.getoutput("gcc demoProgram.c") #command to be executed
print output
I am attempting to to launch a python script from within another python script, but in a minimized console, then return control to the original shell.
I am able to open the required script in a new shell below, but it's not minimized:
#!/usr/bin/env python
import os
import sys
import subprocess
pyTivoPath="c:\pyTivo\pyTivo.py"
print "Testing: Open New Console"
subprocess.Popen([sys.executable, pyTivoPath], creationflags = subprocess.CREATE_NEW_CONSOLE)
print
raw_input("Press Enter to continue...")
Further, I will need to be able to later remotely KILL this shell from the original script, so I suspect I'll need to be explicit in naming the new process. Correct?
Looking for pointers, please. Thanks!
Note: python27 is mandatory for this application. Eventually will also need to work on Mac and Linux.
Do you need to have the other console open? If you now the commands to be sent, then I'd recommend using Popen.communicate(input="Shell commands") and it will automate the process for you.
So you could write something along the lines of:
# Commands to pass into subprocess (each command is separated by a newline)
commands = (
"command1\n" +
"command2\n"
)
# Your process
py_process = subprocess.Popen(*yourprocess_here*, stdin=PIPE, shell=True)
# Feed process the needed input
py_process.communicate(input=commands)
# Terminate when finished
py_process.terminate()
The code above will execute the process you specify and even send commands but it won't open a new console.
I need to run a command via rpyc and get the result of this command.
But whenever I run the command, it is printed on the remote server and can not bring the result.
What I am doing is the following:
import os, sys
import rpyc
conn = rpyc.classic.connect('server_remote')
a = conn.modules.os.system( "ls -lh")
print a
The output of my command is 0 for any command I run.
python get_output.py
0
Use os.popen or subprocess.checked_output instead of system. System just returns the exit code, while the output is printed to your stdout (i.e. you don't get hold of it programmatically)