import os
blah = 'Umm'
print('blah')
os.system('say blah')
"""so I want to make these two things linked,
so that whenever I print something, it says that something
"""
I wanna link these two things, so that whenever I call upon print() it also says what I printed.
Please excuse my (possible) misuse of terminology.
You need to wrap it in a function, then its just a simple case of finding and replacing all of your print with printSay
import os
def printSay(word):
print(word)
os.system('say {word}'.format(word=word))
# Usage
printSay("Hello")
You could run say as a subprocess and write the data to its stdin. I did this on linux with espeak, but I think I got the say command right.
import subprocess
say = subprocess.Popen(["say", "-f", "-"], stdin=subprocess.PIPE)
def myprint(*args):
print(*args)
say.stdin.write((' '.join(args) + '\n').encode('utf-8'))
myprint("hello there")
Related
I have a script that returns an output in the console, eg (not the actual code just an example):
print("Hello World")
I want to be able to catch this output as a string and store it as a variable:
print("Hello World")
# function to catch previous line output and store it as a variable
I'm assuming by the wording in your question that you are running the first print command in a different script than the first one. In that case you can run it using the subprocess module and catch the output like this:
from subprocess import run
result = run(['script.py'], capture_output=True)
previous_output = result.stdout
You can just do that
a = "Hello World !"
print(a)
it's easier than trying to capture it after printing the actual string, but if you insist,
#Blupper already answered your question.
I have a Python(3) script that's calling an external command using the subprocess.call([...]) method:
import subprocess
print("Prefix: ")
subprocess.call(["cmd", "--option", "filename.x"])
The command executes without any errors but the problem is the output.
The output isn't "uniform" and sometimes the program will output:
Program output...
Prefix:
And other times the output will be:
Prefix:
Program output....
The result I'm looking for is:
Prefix: Program output...
I know that in order to achieve this result I need to wait for the subprocess to finish, store it's output and then print the prefix (without \n) with the subprocess' output after it, I just can't figure out how to do it.
Thanks.
First you need to import the sys module, so you can use sys.stdout's write and flush methods.
import sys
You'll also need to import the subprocess module so you can use the subprocess.check_output method.
import subprocess
Use sys.stdout.write instead of print:
sys.stdout.write("Prefix: ")
Then you'll need to replace subprocess.call with subprocess.check_output, which runs the given command and waits for the output.
response = subprocess.check_output(["cmd", "--option", "filename.x"])
NOTE: you need to decode the response because it's a bytes object and not a string.
sys.stdout.write(response.decode("UTF-8"))
And finally you need to flush the output:
sys.stdout.flush()
Here is the final result:
import sys, subprocess
sys.stdout.write("Prefix: ")
response = subprocess.check_output(["cmd", "--option", "filename.x"])
sys.stdout.write(response.decode("UTF-8"))
sys.stdout.flush()
Good luck, hopefully no one else will stumble on this question like I did.
I tries to grab a uart - line and give this string to a shell script;
#!/usr/bin/env python
import os
import serial
ser = serial.Serial('/dev/ttyAMA0', 4800)
while True :
try:
state=ser.readline()
print(state)
except:
pass
So, "state" should given to a shell script now,
like: myscript.sh "This is the serial input..."
but how can I do this?
print(os.system('myscript.sh ').ser.readline())
doesn't work.
Just simple string concatenation passed to the os.system function.
import os
os.system("myscript.sh " + ser.readline())
If myscript can continuously read additional input, you have a much more efficient pipeline.
from subprocess import Popen, PIPE
sink = Popen(['myscript.sh'], stdin=PIPE, stdout=PIPE)
while True:
sink.communicate(ser.readline())
If you have to start a new myscript.sh for every input line, (you'll really want to rethink your design, but) you can, of course:
while True:
subprocess.check_call(['myscript.sh', ser.readline())
Notice how in both cases we avoid a pesky shell.
There are different ways to combine two strings (namely "./myscript.sh" and ser.readLine()), which will then give you the full command to be run by use of os.system. E.g. strings can be arguments of the string.format method:
os.system('myscript.sh {}'.format(ser.readline()))
Also you can just add two strings:
os.system('myscript.sh '+ser.readline())
I am not sure what you want to achieve with the print statement. A better way to handle the call and input/output of your code would be to switch from os to the subprocess module.
I'm trying to make a Python program that can correct exams automaticly, I have extra time and don't wanna wait for my teacher to correct them manually...
Annyways when i use python argv like this:
import sys
def hello(a):
print(a)
a = sys.argv[1:]
hello(a)
And i want to insert a list, I can no longer insert just one variable because of the way argv works, and I can't know how long the list will be because not all tasks are the same. I'm using subprocess.check_output to return the program output after my checker runs it in a cmd window... Now if someone knows a better way to approach correcting the programs without making the students replace their input with sys.argv(if there is a better way to input arguments to a seperate python program when you run it) or can tell me how to fix the argv issue?
You could use Popen.communicate instead of check_output:
echo.py:
print(input())
test.py:
from subprocess import Popen, PIPE
p = Popen(['python3', 'echo.py'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
out, err = p.communicate(input="hello!".encode())
assert out.decode().strip() == "hello!"
I would suggest you to look into OptionParser
I am executing a script which prompts for 2 values one after the other. I want to pass the values from the script itself as I want to automate this.
Using the subprocess module, I can easily pass one value:
suppression_output = subprocess.Popen(cmd_suppression, shell=True,
stdin= subprocess.PIPE,
stdout= subprocess.PIPE).communicate('y') [0]
But passing the 2nd value does not seem to work. If I do something like this:
suppression_output = subprocess.Popen(cmd_suppression, shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE).communicate('y/r/npassword')[0]
You should use \n for the new line instead of /r/n -> 'y\npassword'
As your question is not clear, I assumed you have a program which behaves somewhat like this python script, lets call it script1.py:
import getpass
import sys
firstanswer=raw_input("Do you wish to continue?")
if firstanswer!="y":
sys.exit(0) #leave program
secondanswer=raw_input("Enter your secret password:\n")
#secondanswer=getpass.getpass("Enter your secret password:\n")
print "Password was entered successfully"
#do useful stuff here...
print "I should not print it out, but what the heck: "+secondanswer
It asks for confirmation ("y"), then wants you to enter a password. After that it does "something useful", finally prints the password and then exits
Now to get the first program to be run by a second script script2.py it has to look somewhat like this:
import subprocess
cmd_suppression="python ./testscript.py"
process=subprocess.Popen(cmd_suppression,shell=True\
,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
response=process.communicate("y\npassword")
print response[0]
The output of script2.py:
$ python ./script2.py
Do you wish to continue?Enter your secret password:
Password was entered successfully
I should not print it out, but what the heck: password
A problem can most likely appear if the program uses a special method to get the password in a secure way, i.e. if it uses the line I just commented out in script1.py
secondanswer=getpass.getpass("Enter your secret password:\n")
This case tells you that it is probably not a good idea anyway to pass a password via a script.
Also keep in mind that calling subprocess.Popen with the shell=True option is generally a bad idea too. Use shell=False and provide the command as a list of arguments instead:
cmd_suppression=["python","./testscript2.py"]
process=subprocess.Popen(cmd_suppression,shell=False,\
stdin=subprocess.PIPE,stdout=subprocess.PIPE)
It is mentioned a dozen times in the Subprocess Documentation
Try os.linesep:
import os
from subprocess import Popen, PIPE
p = Popen(args, stdin=PIPE, stdout=PIPE)
output = p.communicate(os.linesep.join(['the first input', 'the 2nd']))[0]
rc = p.returncode
In Python 3.4+, you could use check_output():
import os
from subprocess import check_output
input_values = os.linesep.join(['the first input', 'the 2nd']).encode()
output = check_output(args, input=input_values)
Note: the child script might ask for a password directly from the terminal without using subprocess' stdin/stdout. In that case, you might need pexpect, or pty modules. See Q: Why not just use a pipe (popen())?
import os
from pexpect import run # $ pip install pexpect
nl = os.linesep
output, rc = run(command, events={'nodes.*:': 'y'+nl, 'password:': 'test123'+nl},
withexitstatus=1)