I'm trying to read a character in python so that to perform an action based on the input. I understood there is no easy way to read key strokes in python with the help of Google. I finally found 'readchar' package which is promising but I was not able to make it work in a simple program. Any help is greatly appreciated.
import readchar
def keyprint():
while True:
print "Press 'A' to Start the recording"
print " 'Z' to Stop the recording"
print " 'Enter' to quit the program..."
# Read a key
key = readchar.readkey()
if(key == 'A'):
print "Started Recording..."
elif(key == 'Z'):
print "Stopped Recording..."
elif(key == '\r'):
print "Exiting..."
break
else:
print "Please Use only allowed keys: A, Z, Enter!"
if __name__ == "__main__":
keyprint()
EDIT: Output Error
File "/home/inblueswithu/Documents/LM_DataCollection/keystroke_test.py", line 22, in <module>
keyprint()
File "/home/inblueswithu/Documents/LM_DataCollection/keystroke_test.py", line 10, in keyprint
key = readchar.readkey()
File "/home/inblueswithu/.local/lib/python2.7/site-packages/readchar/readchar.py", line 20, in readkey
c1 = getchar()
File "/home/inblueswithu/.local/lib/python2.7/site-packages/readchar/readchar_linux.py", line 12, in readchar
old_settings = termios.tcgetattr(fd)
termios.error: (25, 'Inappropriate ioctl for device')
Thanks,
inblueswithu
After discussing this issue on github with the creator of the project - magmax (here), I understood that readchar package works only if you try to run it from a terminal but not from any IDE or other non terminal executions. The error is caused because it tries to get the terminal settings which is non existent in this case.
I have been trying to run it from an Wing IDE. The program works great if you try to run it from a terminal.
P.S: magmax suggested to use readchar.keys.ENTER instead of \r . And suggested to have a look at https://github.com/magmax/python-inquirer & its examples
Related
I am working on a project in Python. Currently, only Option 1 works. (i just started this project) It goes through two levels of input and then runs a shell command that makes MacOS show a hidden file. But I am getting an error in the Macos Terminal upon running it: "No matching processes were found." Do you have any idea on why it could be doing this?
My code is too large to fit here, so here is a pastebin link: https://pastebin.com/EuBJjge6
#!/usr/bin/env python
import os
#function by popcnt on stackoverflow
def clear():
os.system('cls' if os.name =='nt' else 'clear')
# thanks to No Spoko on StackOverflow for the original idea, what you see here is modified
def printLogo():
f = open('logo.txt', 'r')
logo = f.read()
print(logo)
f.close()
clear()
printLogo()
print('Welcome to Belowdeck! \n')
#some code ideas from stackoverflow, don't remember the user
menuItem = {}
menuItem['1']="Show hidden files and folders"
menuItem['2']="Hide a file or folder from view"
menuItem['3']="Download files without a web browser"
menuItem['4']="List contents of a folder"
menuItem['5']="View any file's contents"
menuItem['6']="Change permissions of a file"
menuItem['7']="Restore a disk image to a device connected to your Mac"
menuItem['8']="Change the default screenshot location"
menuItem['9']="Change the default screenshot format"
menuItem['10']="Stop apps from syncing to iCloud by default"
menuItem['11']="Check for macOS updates every day instead of every month"
menuItem['12']="Enable a sound when your Mac connects to a power source"
menuItem['13']="Make holding down a key repeat characters"
menuItem['14']="Dull hidden apps in your Dock"
menuItem['15']="Hide non-active apps in your Dock"
menuItem['16']="Add a spacer to your Dock"
menuItem['17']="Change the delay before your Dock slides out"
menuItem['18']="Change the speed at which your Dock slides out"
menuItem['19']="Disable auto-restore in the Preview app"
menuItem['20']="Add a message to the login window"
menuItem['21']="Get rid of Dashboard"
menuItem['22']="Rebuild Spotlight"
menuItem['23']="Destroy your Mac \n"
options=menuItem.keys()
sorted(options)
for entry in options:
print (entry, menuItem[entry])
def option1():
clear()
print("Show hidden files and folders \n")
selection1=input("Would you like to proceed with the operation? (y/n): ")
if selection1 == "y" or selection1 == "Y":
os.system("defaults write com.apple.finder AppleShowAllFiles -bool TRUE && killall finder")
else:
input('Invalid selection! ')
while True:
menuSelection=input("Please select your desired action:")
if menuSelection =='1':
option1()
elif menuSelection == '2':
print ("delete")
elif menuSelection == '3':
print ("find")
elif menuSelection == '4':
print ('4')
else:
print ("Invalid action!")
I don't have access to a Mac, but Googling that error message throws up a lot of hits where people have had issues trying to kill processes. It's very likely that the issue is in line 59. Make sure the commands are correct. Also, avoid using os.system() call to execute shell commands -- it is not recommended. Use the subprocess module instead.
https://docs.python.org/3/library/subprocess.html#subprocess-replacements
https://www.youtube.com/watch?v=oQxTSDh-ECk
i am building a python script that can do certain tasks. I am now focusing on opening and application from the script i used subprocess.call and os.startfile but nothing helped and returned error the code is-
import os
while True:
message=raw_input("Enter your message >> ")
if message=="quit":
exit()
elif message=="bye":
exit()
elif message=="bye bye":
exit()
elif message=="good bye":
exit()
elif message=="see u":
print "Okay then :)"
exit()
elif message=="open games":
print "on to that"
os.start(gnome-mines)
Any help is appreciated
os.startfile is only available with Windows.
Please check here !!!
Instead of os.startfile, use os.system.
Make sure file and user has execution permissions.
you have to enter the complete path of the file to be opened
elif message=="open games":
print "on to that"
os.system("/usr/games/gnome-mines")
Ok so here is part of my code (I have imported sys)
if __name__ == '__main__':
MyCaesarCipher = CaesarCipher() #MyCaesarCipher IS a CaesarCipher()
if len(sys.argv) >1:
#what will it check?
Done = False
while not Done:
print('C Clear All')
print('L Load Encrypted File')
print('R Read Decrypted File')
print('S Store Encrypted File')
print('W Write Decrypted File')
print('O Output Encrypted Text')
print('P Print Decrypted Text')
print('E Encrypt Decrypted Text')
print('D Decrypted Encrypted Text')
print('Q Quit')
print('----------------')
print('Enter Choice>')
So the thing is I want to do is if the command line length is more than 1, the program runs as a script.
This is the instruction:
If no command line arguments are input, then the script enters menu
mode. If more than 1 command line argument (anything other than script
name) is provided during the run of the script it enters single run
mode.
I do not know what this means, though.
What is sys.arvg:
The list of command line arguments passed to a Python script. argv[0] is the script name.
Demo:
File Name: 1.py
import sys
if __name__=="__main__":
print "command arguments:", sys.argv
Output:
$ python 1.py arg1 arg2
command arguments: ['1.py', 'arg1', 'arg2']
$ python 1.py
command arguments: ['1.py']
Your problem is, we have to run code by Command Line Argument and by Menu also.
When User provided the Enter Choice from the command line then use provided value to next process.
If User not provided the Enter Choice from the command line then ask User to Enter Choice from the Menu.
Demo:
File Name: 1.py
import sys
if __name__ == '__main__':
try:
arg_command = sys.argv[1]
except IndexError:
arg_command = ""
Done = False
while not Done:
if arg_command=="":
print('\nMenu')
print('C Clear All')
print('L Load Encrypted File')
print('Q Quit')
print('----------------')
print('Enter Choice>')
command = raw_input('Enter Selection> ').strip()[0].upper()
else:
command = arg_command
#- set arg value to empty to run Menu option again.
arg_command = ""
if command == 'C':
print "In Clear All event."
elif command == 'L':
print "In Clear All event."
elif command == "Q":
break
else:
print "Wrong Selection."
Output:
Enter Choice given from the Command Line:
$ python 1.py C
In Clear All event.
Menu
C Clear All
L Load Encrypted File
Q Quit
----------------
Enter Choice>
Enter Selection> q
$
No Command Line argument.
$ python 1.py
Menu
C Clear All
L Load Encrypted File
Q Quit
----------------
Enter Choice>
Enter Selection> l
In Clear All event.
Menu
C Clear All
L Load Encrypted File
Q Quit
----------------
Enter Choice>
Enter Selection> q
$
Here's the thing, when you're learning a language like this, you can often get by pretty well with just printing out things you don't really understand.
Try this:
Step 1) Make a program that looks like this:
import sys
if __name__ == '__main__':
for idx, arg in enumerate(sys.argv):
print("arg #{} is {}".format(idx, arg))
print len(sys.argv)
After that, run your program from the command line like this:
$ python3 test_script.py
Then, run it like this:
$ python3 test_script.py somearg someother andanother etc "23908452359"
What you discover may be useful to perform this task you are looking to resolve.
Lastly, "menu mode" sounds like the script is going to take input from the user. Thus, you'll need to use input() to do that. It also sounds like you need to come to some decision about when to use menu mode or not, which you've already started to do with your if-test above.
Experiment a bit, though, and you'll figure it out.
The instructions want the script to use the command line arguments to execute the script.
python script.py [arg1] [arg2] [arg3] ....
The args are accessible through sys.argv.
sys.argv = ['script.py', '[arg1]', '[arg2]', '[arg3]']
You will need to use a command line interface instead of the menu interface when args are present.
Since you seem to be pretty new to python here's a simple example using your code. You'll have to complete the menu and the actual code for the menu options but it does use sys.argv
import sys
def menu():
Done = False
while not Done:
print('C Clear All')
print('L Load Encrypted File')
print('R Read Decrypted File')
print('S Store Encrypted File')
print('W Write Decrypted File')
print('O Output Encrypted Text')
print('P Print Decrypted Text')
print('E Encrypt Decrypted Text')
print('D Decrypted Encrypted Text')
print('Q Quit')
print('----------------')
print('Enter Choice>') #should get user input here
Done = True
if __name__=="__main__" :
if len(sys.argv) > 1 :
#Here if an argument is present run it or load the menu
print "run whatever option was entered on the commandline"
else:
menu()
First of all you have to understand what argv is, try creating this script, and call it learning_argv.py
import sys
print(sys.argv)
now try running the script like this:
$ python3 learning_argv.py
$ python3 learning_argv.py a
$ python3 learning_argv.py a b c
$ python3 learning_argv.py AWESOME TEXT
See what argv is?
What you're doing when you test if the length of argv is bigger than one, is basically testing if you're receiving anything beyond the script name.
In the future, you could create a similar structure you created for your menu, to treat arguments sent directly from the command line.
take a look at this quick tutorial in order to better understand argv.
I have pexpect working, but I am having problems printing the output back from it. In my test script below, it creates the ssh connection, and then sends a sudo su -, then my password, and then sends a line that would require sudo access to do (I have also added p.interact() a few times to make sure it is at root). The problem I am having, is with returning the output of the commands I run. In the end I am wanting to run some top commands, and some du -h, and other(much more complex) space commands. But currently when it tries to print p.before, I get:
Traceback (most recent call last):
File "./ssh.py", line 37, in <module>
print p.before()
TypeError: 'str' object is not callable
Here is the script I am working from(edited to remove my pass and such)
#!/usr/bin/env python
import pexpect
import struct, fcntl, os, sys, signal
def sigwinch_passthrough (sig, data):
# Check for buggy platforms (see pexpect.setwinsize()).
if 'TIOCGWINSZ' in dir(termios):
TIOCGWINSZ = termios.TIOCGWINSZ
else:
TIOCGWINSZ = 1074295912 # assume
s = struct.pack ("HHHH", 0, 0, 0, 0)
a = struct.unpack ('HHHH', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ , s))
global global_pexpect_instance
global_pexpect_instance.setwinsize(a[0],a[1])
ssh_newkey = 'Are you sure you want to continue connecting'
p=pexpect.spawn('ssh user#localhost')
i=p.expect([ssh_newkey,'password:',pexpect.EOF,pexpect.TIMEOUT],1)
if i==0:
print "I say yes"
p.sendline('yes')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
print "I give password",
p.sendline("mypassword")
elif i==2:
print "I either got key or connection timeout"
pass
elif i==3: #timeout
pass
global global_pexpect_instance
global_pexpect_instance = p
p.sendline("sudo su -")
p.sendline("mypasswd")
p.sendline("mkdir /home/user/test")
print p.before
I am working off of this link: http://linux.byexamples.com/archives/346/python-how-to-access-ssh-with-pexpect/
Any help is much appreciated.
EDIT: As Armin Rigo pointed out below. I was calling to p.before as a function like p.before(). Stupid mistake on my part, as this explains why I was getting this error today, and not yesterday when I was trying this. After making that change to my script, and modifying the command being sent, print p.before, and no output is returned. Any other ways to return output from a sendline() command?
Use logfile, that logfile is store all output in terminal.use that example code:-
child = pexpect.spawn("ssh user#localhost")
child.logfile = open("/tmp/mylog", "w")
child.expect(".*assword:")
child.send("guest\r")
child.expect(".*\$ ")
child.sendline("python -V\r")
open the log file and see everything in terminals event
To fetch the complete output after sendline use child.read()
e.g.
cmd_resp = pexpect.spawnu(cmd) # for execution of the command
str_to_search = 'Please Enter The Password'
cmd_resp.sendline('yes') # for sending the input 'yes'
resp = cmd_resp.expect([str_to_search, 'password:', EOF], timeout=30) # fetch the output status
if resp == 1:
cmd_resp.sendline(password)
resp = cmd_resp.expect([str_to_search, 'outputString:', EOF], timeout=30)
print(cmd_resp.read()) # to fetch the complete output log
p.before is a string - not a function. To see the output you have to write
print p.before.
Hope this might help you
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.