how to interact with an external script(program) - python

there is a script that expects keyboard input,
i can call that script with os.system('./script') in python,
how is it possible to send back an input to the script from another calling script?
update:
the script is:
$ cat script
#!/usr/bin/python
for i in range(4):
name=raw_input('enter your name')
print 'Welcome %s :) ' % name
when i try without a for loop, it works but it shows the output only when the script quits.
>>> p = subprocess.Popen('./script',stdin=subprocess.PIPE)
>>> p.communicate('navras')
enter your nameWelcome navras :)
when i try it with the foor loop, it throws error, How to display the statements interactive as and when the stdout is updated with new print statements
>>> p.communicate('megna')
enter your nameWelcome megna :)
enter your nameTraceback (most recent call last):
File "./script", line 3, in <module>
name=raw_input('enter your name')
EOFError: EOF when reading a line
(None, None)

You can use subprocess instead of os.system:
p = subprocess.Popen('./script',stdin=subprocess.PIPE)
p.communicate('command')
its not testet

In fact, os.system and os.popen are now deprecated and subprocess is the recommended way to handle all sub process interaction.

Related

raw_input() does not run correctly because syntaxeror

I get this message when running the code:
Python 3.py 3.txt
I'm going to open the your file SMARTIE boy!
If you don't want that - press CONTROL_C-C
If you do want that- Press RETURN
Now i'm actually gonna do it
Now we're gonna truncate it
Write something for your beautiful day.
Traceback (most recent call last):
File "3.py", line 19, in <module>
line1 = raw_input("wefew")
TypeError: 'str' object is not callable
i don't know why
from sys import argv
script, filename = argv
print "I'm going to open the your file SMARTIE boy!"
print "If you don't want that - press CONTROL_C-C"
print "If you do want that- Press RETURN"
raw_input = ("<3")
print "Now i'm actually gonna do it"
mission = open(filename, 'w')
print "Now we're gonna truncate it"
mission.truncate()
print "Write something for your beautiful day."
line1 = raw_input("wefew")
line2 = raw_input("fwefw")
mission.write(line1)
print "Well done! let's close the file now"
mission.close()
Another question - After the code run well how can I print the txt file i changed?
Thanks :)
You are shadowing the raw_input function here: raw_input = ("<3"). That's why you cannot use the original function later on. You probably meant to just call the function:
raw_input("<3")
Another question - After the code run well how can I print the txt file i changed?
Open the file again, read and print the contents.
Suggestion: try reading about the context manager concept that handles opening and closing file objects for you:
with open(filename) as textfile:
print(textfile.read())

How do I pass applescript arguments from a python script?

I have an applescript that takes in two parameters on execution.
on run {targetBuddyPhone, targetMessage}
tell application "Messages"
set targetService to 1st service whose service type = iMessage
set targetBuddy to buddy targetBuddyPhone of targetService
send targetMessage to targetBuddy
end tell
end run
I then want this script to execute from within a python script. I know how to execute a applescript from python, but how do I also give it arguments? Here is the python script that I currently have written out.
#!/usr/bin/env python3
import subprocess
def run_applescript(script, *args):
p = subprocess.Popen(['arch', '-i386', 'osascript', '-e', script] +
[unicode(arg).encode('utf8') for arg in args],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
err = p.wait()
if err:
raise RuntimeError(err, p.stderr.read()[:-1].decode('utf8'))
return p.stdout.read()[:-1].decode('utf8')
The error I receive after trying to execute this code in the terminal is:
Traceback (most recent call last):
File "messageExecuter.py", line 14, in <module>
run_applescript("sendMessage.scpt",1111111111,"hello")
File "messageExecuter.py", line 11, in run_applescript
raise RuntimeError(err, p.stderr.read()[:-1].decode('utf8'))
RuntimeError: (1, u'arch: posix_spawnp: osascript: Bad CPU type in executable')
Clue is in the error message. Delete 'arch', '-i386' from arguments list, as osascript is 64-bit only.

subprocess can't get the stdin input from other process

I use subprocess exchange data between two process
I edit a repeat.py file with:
this file is a example from http://www.doughellmann.com/PyMOTW/subprocess/
import sys
sys.stderr.write('repeater.py: starting\n')
sys.stderr.flush()
while True:
next_line = sys.stdin.readline()
if not next_line:
break
sys.stdout.write(next_line)
sys.stdout.flush()
sys.stderr.write('repeater.py: exiting\n')
sys.stderr.flush()
and run this file in ipython
In [1]: import subprocess
In [2]: f=subprocess.Popen(['python','~/repeat.py'],shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
In [3]: f.stdin.write('teststs\n')
In [4]: f.communicate()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'teststs' is not defined
Out[4]: ('', None)
why teststs is not defined?
You seem to be starting an interactive Python session instead of running repeat.py. Try removing shell=True, it doesn't make sense together with a list of parameters. (Using shell=True is almost always a bad idea, by the way.)
This works with some strange behavior at first 5 key-presses. I don't know why. After that if works fine, and we have access to ls -l, cd, previous commands when press UP, seems command line has full functionality.
#!/bin/python3
import subprocess
import sys
proc = subprocess.Popen(['bash'])
while True:
buff = sys.stdin.readline()
stdoutdata, stderrdata = proc.communicate(buff)
if( stdoutdata ):
print( stdoutdata )
else:
print('n')
break
Here is my similar question.

do not understand this use of sys module

Here is code from a tutorial in A Byte of Python:
import sys
filename = 'poem.txt'
def readfile(filename):
#Print a file to standard output
f = file(filename)
while True:
line = f.readline()
if len(line) == 0:
break
print line,
f.close()
if len(sys.argv) < 2:
print 'No action specified'
sys.exit() //<--This is where the error is occurring
if sys.argv[1].startswith('--'):
option = sys.argv[1][2:] #fetches sys.argv[1] without first 2 char
if option == 'version':
print 'Version 1.2'
elif option == 'help':
print '''\
This program prints files to the standard output.
Any number of files can be specified.
Options include:
--version: Prints the version number
--help: Displays this help'''
else:
print 'Unknown option'
sys.exit()
else:
for filename in sys.argv[1:]:
readfile(filename)
When I run this code, this is the error that appears:
Traceback (most recent call last):
File "C:/Python/sysmodulepr.py", line 17, in <module>
sys.exit()
SystemExit
I don't understand why. Please help.
It's telling you that sys.exit() has executed on line 17 of your program.
The entry for for sys.exit in the Python documentation tells you that this exits your program.
There's no way this line can execute without producing other output, so I think there's something missing in the question.
If you're using IDLE, it will print the stack anyway. Try running your script from the command line, it won't print that error message when executed outside the IDE.
It's not an error. sys.exit() raises SystemExit exception to allow try:... finally block to cleanup used resources
Try in Idle:
import sys
sys.exit()
From documentation for sys.exit():
Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.
edit
The error shouldn't be normally printed unless you're trying to run the script in some interactive interpreters (for example Idle).
It's nothing to worry about, but the script looks like it's standalone, so you should use it as such.

Exit code when python script has unhandled exception

I need a method to run a python script file, and if the script fails with an unhandled exception python should exit with a non-zero exit code. My first try was something like this:
import sys
if __name__ == '__main__':
try:
import <unknown script>
except:
sys.exit(-1)
But it breaks a lot of scripts, due to the __main__ guard often used. Any suggestions for how to do this properly?
Python already does what you're asking:
$ python -c "raise RuntimeError()"
Traceback (most recent call last):
File "<string>", line 1, in <module>
RuntimeError
$ echo $?
1
After some edits from the OP, perhaps you want:
import subprocess
proc = subprocess.Popen(['/usr/bin/python', 'script-name'])
proc.communicate()
if proc.returncode != 0:
# Run failure code
else:
# Run happy code.
Correct me if I am confused here.
if you want to run a script within a script then import isn't the way; you could use exec if you only care about catching exceptions:
namespace = {}
f = open("script.py", "r")
code = f.read()
try:
exec code in namespace
except Exception:
print "bad code"
you can also compile the code first with
compile(code,'<string>','exec')
if you are planning to execute the script more than once and exec the result in the namespace
or use subprocess as described above, if you need to grab the output generated by your script.

Categories

Resources