Keyboard input with timeout in Python
How would you prompt the user for some input but timing out after N seconds?
Google is pointing to a mail thread about it at http://mail.python.org/pipermail/python-list/2006-January/533215.html but it seems not to work. The statement in which the timeout happens, no matter whether it is a sys.input.readline or timer.sleep(), I always get:
<type 'exceptions.TypeError'>: [raw_]input expected at most 1 arguments, got 2
which somehow the except fails to catch.
python timeout keyboard-input
|
show 1 more comment
How would you prompt the user for some input but timing out after N seconds?
Google is pointing to a mail thread about it at http://mail.python.org/pipermail/python-list/2006-January/533215.html but it seems not to work. The statement in which the timeout happens, no matter whether it is a sys.input.readline or timer.sleep(), I always get:
<type 'exceptions.TypeError'>: [raw_]input expected at most 1 arguments, got 2
which somehow the except fails to catch.
python timeout keyboard-input
Is it OK if the solution works in Linux only?
– Nadia Alramli
Aug 26 '09 at 16:28
Yes, Linux only is fine.
– pupeno
Aug 27 '09 at 7:48
related: Python 3 Timed Input
– jfs
Oct 20 '14 at 2:44
possible duplicate of Timeout on a Python function call
– n611x007
Mar 13 '15 at 13:04
related: raw_input and timeout /3471461
– n611x007
Mar 13 '15 at 13:06
|
show 1 more comment
How would you prompt the user for some input but timing out after N seconds?
Google is pointing to a mail thread about it at http://mail.python.org/pipermail/python-list/2006-January/533215.html but it seems not to work. The statement in which the timeout happens, no matter whether it is a sys.input.readline or timer.sleep(), I always get:
<type 'exceptions.TypeError'>: [raw_]input expected at most 1 arguments, got 2
which somehow the except fails to catch.
python timeout keyboard-input
How would you prompt the user for some input but timing out after N seconds?
Google is pointing to a mail thread about it at http://mail.python.org/pipermail/python-list/2006-January/533215.html but it seems not to work. The statement in which the timeout happens, no matter whether it is a sys.input.readline or timer.sleep(), I always get:
<type 'exceptions.TypeError'>: [raw_]input expected at most 1 arguments, got 2
which somehow the except fails to catch.
python timeout keyboard-input
python timeout keyboard-input
asked Aug 26 '09 at 15:19
pupenopupeno
105k99271435
105k99271435
Is it OK if the solution works in Linux only?
– Nadia Alramli
Aug 26 '09 at 16:28
Yes, Linux only is fine.
– pupeno
Aug 27 '09 at 7:48
related: Python 3 Timed Input
– jfs
Oct 20 '14 at 2:44
possible duplicate of Timeout on a Python function call
– n611x007
Mar 13 '15 at 13:04
related: raw_input and timeout /3471461
– n611x007
Mar 13 '15 at 13:06
|
show 1 more comment
Is it OK if the solution works in Linux only?
– Nadia Alramli
Aug 26 '09 at 16:28
Yes, Linux only is fine.
– pupeno
Aug 27 '09 at 7:48
related: Python 3 Timed Input
– jfs
Oct 20 '14 at 2:44
possible duplicate of Timeout on a Python function call
– n611x007
Mar 13 '15 at 13:04
related: raw_input and timeout /3471461
– n611x007
Mar 13 '15 at 13:06
Is it OK if the solution works in Linux only?
– Nadia Alramli
Aug 26 '09 at 16:28
Is it OK if the solution works in Linux only?
– Nadia Alramli
Aug 26 '09 at 16:28
Yes, Linux only is fine.
– pupeno
Aug 27 '09 at 7:48
Yes, Linux only is fine.
– pupeno
Aug 27 '09 at 7:48
related: Python 3 Timed Input
– jfs
Oct 20 '14 at 2:44
related: Python 3 Timed Input
– jfs
Oct 20 '14 at 2:44
possible duplicate of Timeout on a Python function call
– n611x007
Mar 13 '15 at 13:04
possible duplicate of Timeout on a Python function call
– n611x007
Mar 13 '15 at 13:04
related: raw_input and timeout /3471461
– n611x007
Mar 13 '15 at 13:06
related: raw_input and timeout /3471461
– n611x007
Mar 13 '15 at 13:06
|
show 1 more comment
11 Answers
11
active
oldest
votes
The example you have linked to is wrong and the exception is actually occuring when calling alarm handler instead of when read blocks. Better try this:
import signal
TIMEOUT = 5 # number of seconds your want for timeout
def interrupted(signum, frame):
"called when read times out"
print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
print 'You have 5 seconds to type in your stuff...'
foo = raw_input()
return foo
except:
# timeout
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s
7
Nice solution, this only works on Linux though.
– Nadia Alramli
Aug 26 '09 at 19:25
I have been struggling with getting a keyboard input with timeout today. I just wanted a way to stop the reproduction of images from the hard-drive so that I can stop it just pressing a key, so I wanted a small timeout (33ms). I just want to point out that some solutions that you'll find on stackoverflow don't work on IDLE!! (I don't know why). You have to execute them on terminal. And also, the most helpful code I have found on internet is this one: home.wlu.edu/~levys/software/kbhit.py . Good luck!
– jespestana
Jun 12 '13 at 23:47
1
I was trying this solution, and this was not working in python3. You have to raise an error in interrupted function to catch that exception in defined input function - that will make it work in python3. :)
– rnbguy
Jun 4 '14 at 18:41
1
Indentation error on line 7.
– anonymous
Jul 21 '17 at 23:22
4
This does not work for me. It just prints"interrupted"
after 5 seconds, but it does not actually stop theinput
. It still waits for Enter to be pressed, and it even prints any text I enter after the "Interrupted" message appears. Tested on Linux with Python 2 and 3.
– tobias_k
Feb 1 '18 at 12:01
|
show 1 more comment
Using a select call is shorter, and should be much more portable
import sys, select
print "You have ten seconds to answer!"
i, o, e = select.select( [sys.stdin], , , 10 )
if (i):
print "You said", sys.stdin.readline().strip()
else:
print "You said nothing!"
3
+1 for cross platform solution.
– Great Turtle
Jun 4 '10 at 15:06
27
I just tested and this does NOT work for windows. Select is available, but on windows the input to select can only be a socket - sys.stdin and file descriptors are unix. I'll be sure to test first next time.
– Great Turtle
Jun 4 '10 at 15:19
12
Darn. Well, what self respecting programmer uses windows anyway? ;) For simple user input I guess it could be done with a loop around "kbhit", which detects keyboard presses, and "getch" with "time.sleep" to break after a timeout. But it will be ugly.
– Pontus
Jun 10 '10 at 16:26
add a comment |
Not a Python solution, but...
I ran in to this problem with a script running under CentOS (Linux), and what worked for my situation was just running the Bash "read -t" command in a subprocess. Brutal disgusting hack, I know, but I feel guilty enough about how well it worked that I wanted to share it with everyone here.
import subprocess
subprocess.call('read -t 30', shell=True)
All I needed was something that waited for 30 seconds unless the ENTER key was pressed. This worked great.
add a comment |
And here's one that works on Windows
I haven't been able to get any of these examples to work on Windows so I've merged some different StackOverflow answers to get the following:
import threading, msvcrt
import sys
def readInput(caption, default, timeout = 5):
class KeyboardThread(threading.Thread):
def run(self):
self.timedout = False
self.input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13:
break
elif ord(chr) >= 32:
self.input += chr
if len(self.input) == 0 and self.timedout:
break
sys.stdout.write('%s(%s):'%(caption, default));
result = default
it = KeyboardThread()
it.start()
it.join(timeout)
it.timedout = True
if len(it.input) > 0:
# wait for rest of input
it.join()
result = it.input
print '' # needed to move to next line
return result
# and some examples of usage
ans = readInput('Please type a name', 'john')
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 )
print 'The number is %s' % ans
1
I just realised I didn't need to use a thread. See the same code but without a thread at stackoverflow.com/questions/3471461/raw-input-and-timeout/…
– Paul
Oct 12 '10 at 3:53
this does not seem to work on windows. I'm running your code, verbatim with the exception of changing Print to py3 syntax, and adding a stdout.flush(). Windows7, python3.6
– mike
Jan 23 '17 at 16:51
add a comment |
Paul's answer did not quite work. Modified code below which works for me on
windows 7 x64
vanilla CMD shell (eg, not git-bash or other non-M$ shell)
-- nothing
msvcrt
works in git-bash it appears.python 3.6
(I'm posting a new answer, because editing Paul's answer directly would change it from python 2.x-->3.x, which seems too much for an edit (py2 is still in use)
import sys, time, msvcrt
def readInput( caption, default, timeout = 5):
start_time = time.time()
sys.stdout.write('%s(%s):'%(caption, default))
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
byte_arr = msvcrt.getche()
if ord(byte_arr) == 13: # enter_key
break
elif ord(byte_arr) >= 32: #space_char
input += "".join(map(chr,byte_arr))
if len(input) == 0 and (time.time() - start_time) > timeout:
print("timing out, using default value.")
break
print('') # needed to move to next line
if len(input) > 0:
return input
else:
return default
# and some examples of usage
ans = readInput('Please type a name', 'john')
print( 'The name is %s' % ans)
ans = readInput('Please enter a number', 10 )
print( 'The number is %s' % ans)
formatting is not working as i expect here. I'm stumped, have asked over at Meta: meta.stackexchange.com/q/290162/208995
– mike
Jan 23 '17 at 17:51
add a comment |
Following code worked for me.
I used two threads one to get the raw_Input and another to wait for a specific time.
If any of the thread exits, both the thread is terminated and returned.
def _input(msg, q):
ra = raw_input(msg)
if ra:
q.put(ra)
else:
q.put("None")
return
def _slp(tm, q):
time.sleep(tm)
q.put("Timeout")
return
def wait_for_input(msg="Press Enter to continue", time=10):
q = Queue.Queue()
th = threading.Thread(target=_input, args=(msg, q,))
tt = threading.Thread(target=_slp, args=(time, q,))
th.start()
tt.start()
ret = None
while True:
ret = q.get()
if ret:
th._Thread__stop()
tt._Thread__stop()
return ret
return ret
print time.ctime()
t= wait_for_input()
print "nResponse :",t
print time.ctime()
add a comment |
I spent a good twenty minutes or so on this, so I thought it was worth a shot to put this up here. It is directly building off of user137673's answer, though. I found it most useful to do something like this:
#! /usr/bin/env python
import signal
timeout = None
def main():
inp = stdinWait("You have 5 seconds to type text and press <Enter>... ", "[no text]", 5, "Aw man! You ran out of time!!")
if not timeout:
print "You entered", inp
else:
print "You didn't enter anything because I'm on a tight schedule!"
def stdinWait(text, default, time, timeoutDisplay = None, **kwargs):
signal.signal(signal.SIGALRM, interrupt)
signal.alarm(time) # sets timeout
global timeout
try:
inp = raw_input(text)
signal.alarm(0)
timeout = False
except (KeyboardInterrupt):
printInterrupt = kwargs.get("printInterrupt", True)
if printInterrupt:
print "Keyboard interrupt"
timeout = True # Do this so you don't mistakenly get input when there is none
inp = default
except:
timeout = True
if not timeoutDisplay is None:
print timeoutDisplay
signal.alarm(0)
inp = default
return inp
def interrupt(signum, frame):
raise Exception("")
if __name__ == "__main__":
main()
Great solution. Works very fine in Python3. Can't up-vote it enough.
– Regis May
Apr 25 '18 at 14:46
add a comment |
Analogous to Locane's for windows:
import subprocess
subprocess.call('timeout /T 30')
2
If it matters, timeout was introduced with or after Windows Vista.
– DevPlayer
Sep 15 '16 at 12:43
add a comment |
Here is a portable and simple Python 3 solution using threads.
This is the only one that worked for me while being cross-platform.
Other things I tried all had problems:
- Using signal.SIGALRM: not working on Windows
- Using select call: not working on Windows
- Using force-terminate of a process (instead of thread): stdin cannot be used in new process (stdin is auto-closed)
- Redirection stdin to StringIO and writing directly to stdin: will still write to previous stdin if input() has already been called (see https://stackoverflow.com/a/15055639/9624704)
from threading import Thread
class myClass:
_input = None
def __init__(self):
get_input_thread = Thread(target=self.get_input)
get_input_thread.daemon = True # Otherwise the thread won't be terminated when the main program terminates.
get_input_thread.start()
get_input_thread.join(timeout=20)
if myClass._input is None:
print("No input was given within 20 seconds")
else:
print("Input given was: ".format(myClass._input))
@classmethod
def get_input(cls):
cls._input = input("")
return
add a comment |
Since this question seems to serve as a duplicate target, here the link to my accepted answer in a duplicate question.
Features
- Platform independent (Unix / Windows).
- StdLib only, no external dependencies.
- Threads only, no Subprocesses.
- Immediate interrupt at timeout.
- Clean shutdown of prompter at timeout.
- Unlimited inputs possible during time span.
- Easy expandable PromptManager class.
- Program may resume after timeout, multiple runs of prompter instances possible without program restart.
add a comment |
A late answer :)
I would do something like this:
from time import sleep
print('Please provide input in 20 seconds! (Hit Ctrl-C to start)')
try:
for i in range(0,20):
sleep(1) # could use a backward counter to be preeety :)
print('No input is given.')
except KeyboardInterrupt:
raw_input('Input x:')
print('You, you! You know something.')
I know this is not the same but many real life problem could be solved this way. (I usually need timeout for user input when I want something to continue running if the user not there at the moment.)
Hope this at least partially helps. (If anyone reads it anyway :) )
1
No, KeyboardInterrupt exception occurs when users sends an interrupt signal, usually by hitting Ctrl+C on the terminal.
– Radian
Oct 31 '12 at 9:42
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1335507%2fkeyboard-input-with-timeout-in-python%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
11 Answers
11
active
oldest
votes
11 Answers
11
active
oldest
votes
active
oldest
votes
active
oldest
votes
The example you have linked to is wrong and the exception is actually occuring when calling alarm handler instead of when read blocks. Better try this:
import signal
TIMEOUT = 5 # number of seconds your want for timeout
def interrupted(signum, frame):
"called when read times out"
print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
print 'You have 5 seconds to type in your stuff...'
foo = raw_input()
return foo
except:
# timeout
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s
7
Nice solution, this only works on Linux though.
– Nadia Alramli
Aug 26 '09 at 19:25
I have been struggling with getting a keyboard input with timeout today. I just wanted a way to stop the reproduction of images from the hard-drive so that I can stop it just pressing a key, so I wanted a small timeout (33ms). I just want to point out that some solutions that you'll find on stackoverflow don't work on IDLE!! (I don't know why). You have to execute them on terminal. And also, the most helpful code I have found on internet is this one: home.wlu.edu/~levys/software/kbhit.py . Good luck!
– jespestana
Jun 12 '13 at 23:47
1
I was trying this solution, and this was not working in python3. You have to raise an error in interrupted function to catch that exception in defined input function - that will make it work in python3. :)
– rnbguy
Jun 4 '14 at 18:41
1
Indentation error on line 7.
– anonymous
Jul 21 '17 at 23:22
4
This does not work for me. It just prints"interrupted"
after 5 seconds, but it does not actually stop theinput
. It still waits for Enter to be pressed, and it even prints any text I enter after the "Interrupted" message appears. Tested on Linux with Python 2 and 3.
– tobias_k
Feb 1 '18 at 12:01
|
show 1 more comment
The example you have linked to is wrong and the exception is actually occuring when calling alarm handler instead of when read blocks. Better try this:
import signal
TIMEOUT = 5 # number of seconds your want for timeout
def interrupted(signum, frame):
"called when read times out"
print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
print 'You have 5 seconds to type in your stuff...'
foo = raw_input()
return foo
except:
# timeout
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s
7
Nice solution, this only works on Linux though.
– Nadia Alramli
Aug 26 '09 at 19:25
I have been struggling with getting a keyboard input with timeout today. I just wanted a way to stop the reproduction of images from the hard-drive so that I can stop it just pressing a key, so I wanted a small timeout (33ms). I just want to point out that some solutions that you'll find on stackoverflow don't work on IDLE!! (I don't know why). You have to execute them on terminal. And also, the most helpful code I have found on internet is this one: home.wlu.edu/~levys/software/kbhit.py . Good luck!
– jespestana
Jun 12 '13 at 23:47
1
I was trying this solution, and this was not working in python3. You have to raise an error in interrupted function to catch that exception in defined input function - that will make it work in python3. :)
– rnbguy
Jun 4 '14 at 18:41
1
Indentation error on line 7.
– anonymous
Jul 21 '17 at 23:22
4
This does not work for me. It just prints"interrupted"
after 5 seconds, but it does not actually stop theinput
. It still waits for Enter to be pressed, and it even prints any text I enter after the "Interrupted" message appears. Tested on Linux with Python 2 and 3.
– tobias_k
Feb 1 '18 at 12:01
|
show 1 more comment
The example you have linked to is wrong and the exception is actually occuring when calling alarm handler instead of when read blocks. Better try this:
import signal
TIMEOUT = 5 # number of seconds your want for timeout
def interrupted(signum, frame):
"called when read times out"
print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
print 'You have 5 seconds to type in your stuff...'
foo = raw_input()
return foo
except:
# timeout
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s
The example you have linked to is wrong and the exception is actually occuring when calling alarm handler instead of when read blocks. Better try this:
import signal
TIMEOUT = 5 # number of seconds your want for timeout
def interrupted(signum, frame):
"called when read times out"
print 'interrupted!'
signal.signal(signal.SIGALRM, interrupted)
def input():
try:
print 'You have 5 seconds to type in your stuff...'
foo = raw_input()
return foo
except:
# timeout
return
# set alarm
signal.alarm(TIMEOUT)
s = input()
# disable the alarm after success
signal.alarm(0)
print 'You typed', s
answered Aug 26 '09 at 18:50
user137673user137673
1,19787
1,19787
7
Nice solution, this only works on Linux though.
– Nadia Alramli
Aug 26 '09 at 19:25
I have been struggling with getting a keyboard input with timeout today. I just wanted a way to stop the reproduction of images from the hard-drive so that I can stop it just pressing a key, so I wanted a small timeout (33ms). I just want to point out that some solutions that you'll find on stackoverflow don't work on IDLE!! (I don't know why). You have to execute them on terminal. And also, the most helpful code I have found on internet is this one: home.wlu.edu/~levys/software/kbhit.py . Good luck!
– jespestana
Jun 12 '13 at 23:47
1
I was trying this solution, and this was not working in python3. You have to raise an error in interrupted function to catch that exception in defined input function - that will make it work in python3. :)
– rnbguy
Jun 4 '14 at 18:41
1
Indentation error on line 7.
– anonymous
Jul 21 '17 at 23:22
4
This does not work for me. It just prints"interrupted"
after 5 seconds, but it does not actually stop theinput
. It still waits for Enter to be pressed, and it even prints any text I enter after the "Interrupted" message appears. Tested on Linux with Python 2 and 3.
– tobias_k
Feb 1 '18 at 12:01
|
show 1 more comment
7
Nice solution, this only works on Linux though.
– Nadia Alramli
Aug 26 '09 at 19:25
I have been struggling with getting a keyboard input with timeout today. I just wanted a way to stop the reproduction of images from the hard-drive so that I can stop it just pressing a key, so I wanted a small timeout (33ms). I just want to point out that some solutions that you'll find on stackoverflow don't work on IDLE!! (I don't know why). You have to execute them on terminal. And also, the most helpful code I have found on internet is this one: home.wlu.edu/~levys/software/kbhit.py . Good luck!
– jespestana
Jun 12 '13 at 23:47
1
I was trying this solution, and this was not working in python3. You have to raise an error in interrupted function to catch that exception in defined input function - that will make it work in python3. :)
– rnbguy
Jun 4 '14 at 18:41
1
Indentation error on line 7.
– anonymous
Jul 21 '17 at 23:22
4
This does not work for me. It just prints"interrupted"
after 5 seconds, but it does not actually stop theinput
. It still waits for Enter to be pressed, and it even prints any text I enter after the "Interrupted" message appears. Tested on Linux with Python 2 and 3.
– tobias_k
Feb 1 '18 at 12:01
7
7
Nice solution, this only works on Linux though.
– Nadia Alramli
Aug 26 '09 at 19:25
Nice solution, this only works on Linux though.
– Nadia Alramli
Aug 26 '09 at 19:25
I have been struggling with getting a keyboard input with timeout today. I just wanted a way to stop the reproduction of images from the hard-drive so that I can stop it just pressing a key, so I wanted a small timeout (33ms). I just want to point out that some solutions that you'll find on stackoverflow don't work on IDLE!! (I don't know why). You have to execute them on terminal. And also, the most helpful code I have found on internet is this one: home.wlu.edu/~levys/software/kbhit.py . Good luck!
– jespestana
Jun 12 '13 at 23:47
I have been struggling with getting a keyboard input with timeout today. I just wanted a way to stop the reproduction of images from the hard-drive so that I can stop it just pressing a key, so I wanted a small timeout (33ms). I just want to point out that some solutions that you'll find on stackoverflow don't work on IDLE!! (I don't know why). You have to execute them on terminal. And also, the most helpful code I have found on internet is this one: home.wlu.edu/~levys/software/kbhit.py . Good luck!
– jespestana
Jun 12 '13 at 23:47
1
1
I was trying this solution, and this was not working in python3. You have to raise an error in interrupted function to catch that exception in defined input function - that will make it work in python3. :)
– rnbguy
Jun 4 '14 at 18:41
I was trying this solution, and this was not working in python3. You have to raise an error in interrupted function to catch that exception in defined input function - that will make it work in python3. :)
– rnbguy
Jun 4 '14 at 18:41
1
1
Indentation error on line 7.
– anonymous
Jul 21 '17 at 23:22
Indentation error on line 7.
– anonymous
Jul 21 '17 at 23:22
4
4
This does not work for me. It just prints
"interrupted"
after 5 seconds, but it does not actually stop the input
. It still waits for Enter to be pressed, and it even prints any text I enter after the "Interrupted" message appears. Tested on Linux with Python 2 and 3.– tobias_k
Feb 1 '18 at 12:01
This does not work for me. It just prints
"interrupted"
after 5 seconds, but it does not actually stop the input
. It still waits for Enter to be pressed, and it even prints any text I enter after the "Interrupted" message appears. Tested on Linux with Python 2 and 3.– tobias_k
Feb 1 '18 at 12:01
|
show 1 more comment
Using a select call is shorter, and should be much more portable
import sys, select
print "You have ten seconds to answer!"
i, o, e = select.select( [sys.stdin], , , 10 )
if (i):
print "You said", sys.stdin.readline().strip()
else:
print "You said nothing!"
3
+1 for cross platform solution.
– Great Turtle
Jun 4 '10 at 15:06
27
I just tested and this does NOT work for windows. Select is available, but on windows the input to select can only be a socket - sys.stdin and file descriptors are unix. I'll be sure to test first next time.
– Great Turtle
Jun 4 '10 at 15:19
12
Darn. Well, what self respecting programmer uses windows anyway? ;) For simple user input I guess it could be done with a loop around "kbhit", which detects keyboard presses, and "getch" with "time.sleep" to break after a timeout. But it will be ugly.
– Pontus
Jun 10 '10 at 16:26
add a comment |
Using a select call is shorter, and should be much more portable
import sys, select
print "You have ten seconds to answer!"
i, o, e = select.select( [sys.stdin], , , 10 )
if (i):
print "You said", sys.stdin.readline().strip()
else:
print "You said nothing!"
3
+1 for cross platform solution.
– Great Turtle
Jun 4 '10 at 15:06
27
I just tested and this does NOT work for windows. Select is available, but on windows the input to select can only be a socket - sys.stdin and file descriptors are unix. I'll be sure to test first next time.
– Great Turtle
Jun 4 '10 at 15:19
12
Darn. Well, what self respecting programmer uses windows anyway? ;) For simple user input I guess it could be done with a loop around "kbhit", which detects keyboard presses, and "getch" with "time.sleep" to break after a timeout. But it will be ugly.
– Pontus
Jun 10 '10 at 16:26
add a comment |
Using a select call is shorter, and should be much more portable
import sys, select
print "You have ten seconds to answer!"
i, o, e = select.select( [sys.stdin], , , 10 )
if (i):
print "You said", sys.stdin.readline().strip()
else:
print "You said nothing!"
Using a select call is shorter, and should be much more portable
import sys, select
print "You have ten seconds to answer!"
i, o, e = select.select( [sys.stdin], , , 10 )
if (i):
print "You said", sys.stdin.readline().strip()
else:
print "You said nothing!"
answered May 25 '10 at 11:18
PontusPontus
1,121186
1,121186
3
+1 for cross platform solution.
– Great Turtle
Jun 4 '10 at 15:06
27
I just tested and this does NOT work for windows. Select is available, but on windows the input to select can only be a socket - sys.stdin and file descriptors are unix. I'll be sure to test first next time.
– Great Turtle
Jun 4 '10 at 15:19
12
Darn. Well, what self respecting programmer uses windows anyway? ;) For simple user input I guess it could be done with a loop around "kbhit", which detects keyboard presses, and "getch" with "time.sleep" to break after a timeout. But it will be ugly.
– Pontus
Jun 10 '10 at 16:26
add a comment |
3
+1 for cross platform solution.
– Great Turtle
Jun 4 '10 at 15:06
27
I just tested and this does NOT work for windows. Select is available, but on windows the input to select can only be a socket - sys.stdin and file descriptors are unix. I'll be sure to test first next time.
– Great Turtle
Jun 4 '10 at 15:19
12
Darn. Well, what self respecting programmer uses windows anyway? ;) For simple user input I guess it could be done with a loop around "kbhit", which detects keyboard presses, and "getch" with "time.sleep" to break after a timeout. But it will be ugly.
– Pontus
Jun 10 '10 at 16:26
3
3
+1 for cross platform solution.
– Great Turtle
Jun 4 '10 at 15:06
+1 for cross platform solution.
– Great Turtle
Jun 4 '10 at 15:06
27
27
I just tested and this does NOT work for windows. Select is available, but on windows the input to select can only be a socket - sys.stdin and file descriptors are unix. I'll be sure to test first next time.
– Great Turtle
Jun 4 '10 at 15:19
I just tested and this does NOT work for windows. Select is available, but on windows the input to select can only be a socket - sys.stdin and file descriptors are unix. I'll be sure to test first next time.
– Great Turtle
Jun 4 '10 at 15:19
12
12
Darn. Well, what self respecting programmer uses windows anyway? ;) For simple user input I guess it could be done with a loop around "kbhit", which detects keyboard presses, and "getch" with "time.sleep" to break after a timeout. But it will be ugly.
– Pontus
Jun 10 '10 at 16:26
Darn. Well, what self respecting programmer uses windows anyway? ;) For simple user input I guess it could be done with a loop around "kbhit", which detects keyboard presses, and "getch" with "time.sleep" to break after a timeout. But it will be ugly.
– Pontus
Jun 10 '10 at 16:26
add a comment |
Not a Python solution, but...
I ran in to this problem with a script running under CentOS (Linux), and what worked for my situation was just running the Bash "read -t" command in a subprocess. Brutal disgusting hack, I know, but I feel guilty enough about how well it worked that I wanted to share it with everyone here.
import subprocess
subprocess.call('read -t 30', shell=True)
All I needed was something that waited for 30 seconds unless the ENTER key was pressed. This worked great.
add a comment |
Not a Python solution, but...
I ran in to this problem with a script running under CentOS (Linux), and what worked for my situation was just running the Bash "read -t" command in a subprocess. Brutal disgusting hack, I know, but I feel guilty enough about how well it worked that I wanted to share it with everyone here.
import subprocess
subprocess.call('read -t 30', shell=True)
All I needed was something that waited for 30 seconds unless the ENTER key was pressed. This worked great.
add a comment |
Not a Python solution, but...
I ran in to this problem with a script running under CentOS (Linux), and what worked for my situation was just running the Bash "read -t" command in a subprocess. Brutal disgusting hack, I know, but I feel guilty enough about how well it worked that I wanted to share it with everyone here.
import subprocess
subprocess.call('read -t 30', shell=True)
All I needed was something that waited for 30 seconds unless the ENTER key was pressed. This worked great.
Not a Python solution, but...
I ran in to this problem with a script running under CentOS (Linux), and what worked for my situation was just running the Bash "read -t" command in a subprocess. Brutal disgusting hack, I know, but I feel guilty enough about how well it worked that I wanted to share it with everyone here.
import subprocess
subprocess.call('read -t 30', shell=True)
All I needed was something that waited for 30 seconds unless the ENTER key was pressed. This worked great.
edited Dec 1 '14 at 6:52
answered Dec 1 '14 at 6:23
LocaneLocane
1,54411623
1,54411623
add a comment |
add a comment |
And here's one that works on Windows
I haven't been able to get any of these examples to work on Windows so I've merged some different StackOverflow answers to get the following:
import threading, msvcrt
import sys
def readInput(caption, default, timeout = 5):
class KeyboardThread(threading.Thread):
def run(self):
self.timedout = False
self.input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13:
break
elif ord(chr) >= 32:
self.input += chr
if len(self.input) == 0 and self.timedout:
break
sys.stdout.write('%s(%s):'%(caption, default));
result = default
it = KeyboardThread()
it.start()
it.join(timeout)
it.timedout = True
if len(it.input) > 0:
# wait for rest of input
it.join()
result = it.input
print '' # needed to move to next line
return result
# and some examples of usage
ans = readInput('Please type a name', 'john')
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 )
print 'The number is %s' % ans
1
I just realised I didn't need to use a thread. See the same code but without a thread at stackoverflow.com/questions/3471461/raw-input-and-timeout/…
– Paul
Oct 12 '10 at 3:53
this does not seem to work on windows. I'm running your code, verbatim with the exception of changing Print to py3 syntax, and adding a stdout.flush(). Windows7, python3.6
– mike
Jan 23 '17 at 16:51
add a comment |
And here's one that works on Windows
I haven't been able to get any of these examples to work on Windows so I've merged some different StackOverflow answers to get the following:
import threading, msvcrt
import sys
def readInput(caption, default, timeout = 5):
class KeyboardThread(threading.Thread):
def run(self):
self.timedout = False
self.input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13:
break
elif ord(chr) >= 32:
self.input += chr
if len(self.input) == 0 and self.timedout:
break
sys.stdout.write('%s(%s):'%(caption, default));
result = default
it = KeyboardThread()
it.start()
it.join(timeout)
it.timedout = True
if len(it.input) > 0:
# wait for rest of input
it.join()
result = it.input
print '' # needed to move to next line
return result
# and some examples of usage
ans = readInput('Please type a name', 'john')
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 )
print 'The number is %s' % ans
1
I just realised I didn't need to use a thread. See the same code but without a thread at stackoverflow.com/questions/3471461/raw-input-and-timeout/…
– Paul
Oct 12 '10 at 3:53
this does not seem to work on windows. I'm running your code, verbatim with the exception of changing Print to py3 syntax, and adding a stdout.flush(). Windows7, python3.6
– mike
Jan 23 '17 at 16:51
add a comment |
And here's one that works on Windows
I haven't been able to get any of these examples to work on Windows so I've merged some different StackOverflow answers to get the following:
import threading, msvcrt
import sys
def readInput(caption, default, timeout = 5):
class KeyboardThread(threading.Thread):
def run(self):
self.timedout = False
self.input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13:
break
elif ord(chr) >= 32:
self.input += chr
if len(self.input) == 0 and self.timedout:
break
sys.stdout.write('%s(%s):'%(caption, default));
result = default
it = KeyboardThread()
it.start()
it.join(timeout)
it.timedout = True
if len(it.input) > 0:
# wait for rest of input
it.join()
result = it.input
print '' # needed to move to next line
return result
# and some examples of usage
ans = readInput('Please type a name', 'john')
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 )
print 'The number is %s' % ans
And here's one that works on Windows
I haven't been able to get any of these examples to work on Windows so I've merged some different StackOverflow answers to get the following:
import threading, msvcrt
import sys
def readInput(caption, default, timeout = 5):
class KeyboardThread(threading.Thread):
def run(self):
self.timedout = False
self.input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13:
break
elif ord(chr) >= 32:
self.input += chr
if len(self.input) == 0 and self.timedout:
break
sys.stdout.write('%s(%s):'%(caption, default));
result = default
it = KeyboardThread()
it.start()
it.join(timeout)
it.timedout = True
if len(it.input) > 0:
# wait for rest of input
it.join()
result = it.input
print '' # needed to move to next line
return result
# and some examples of usage
ans = readInput('Please type a name', 'john')
print 'The name is %s' % ans
ans = readInput('Please enter a number', 10 )
print 'The number is %s' % ans
edited Oct 12 '10 at 3:33
answered Oct 12 '10 at 3:25
PaulPaul
18924
18924
1
I just realised I didn't need to use a thread. See the same code but without a thread at stackoverflow.com/questions/3471461/raw-input-and-timeout/…
– Paul
Oct 12 '10 at 3:53
this does not seem to work on windows. I'm running your code, verbatim with the exception of changing Print to py3 syntax, and adding a stdout.flush(). Windows7, python3.6
– mike
Jan 23 '17 at 16:51
add a comment |
1
I just realised I didn't need to use a thread. See the same code but without a thread at stackoverflow.com/questions/3471461/raw-input-and-timeout/…
– Paul
Oct 12 '10 at 3:53
this does not seem to work on windows. I'm running your code, verbatim with the exception of changing Print to py3 syntax, and adding a stdout.flush(). Windows7, python3.6
– mike
Jan 23 '17 at 16:51
1
1
I just realised I didn't need to use a thread. See the same code but without a thread at stackoverflow.com/questions/3471461/raw-input-and-timeout/…
– Paul
Oct 12 '10 at 3:53
I just realised I didn't need to use a thread. See the same code but without a thread at stackoverflow.com/questions/3471461/raw-input-and-timeout/…
– Paul
Oct 12 '10 at 3:53
this does not seem to work on windows. I'm running your code, verbatim with the exception of changing Print to py3 syntax, and adding a stdout.flush(). Windows7, python3.6
– mike
Jan 23 '17 at 16:51
this does not seem to work on windows. I'm running your code, verbatim with the exception of changing Print to py3 syntax, and adding a stdout.flush(). Windows7, python3.6
– mike
Jan 23 '17 at 16:51
add a comment |
Paul's answer did not quite work. Modified code below which works for me on
windows 7 x64
vanilla CMD shell (eg, not git-bash or other non-M$ shell)
-- nothing
msvcrt
works in git-bash it appears.python 3.6
(I'm posting a new answer, because editing Paul's answer directly would change it from python 2.x-->3.x, which seems too much for an edit (py2 is still in use)
import sys, time, msvcrt
def readInput( caption, default, timeout = 5):
start_time = time.time()
sys.stdout.write('%s(%s):'%(caption, default))
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
byte_arr = msvcrt.getche()
if ord(byte_arr) == 13: # enter_key
break
elif ord(byte_arr) >= 32: #space_char
input += "".join(map(chr,byte_arr))
if len(input) == 0 and (time.time() - start_time) > timeout:
print("timing out, using default value.")
break
print('') # needed to move to next line
if len(input) > 0:
return input
else:
return default
# and some examples of usage
ans = readInput('Please type a name', 'john')
print( 'The name is %s' % ans)
ans = readInput('Please enter a number', 10 )
print( 'The number is %s' % ans)
formatting is not working as i expect here. I'm stumped, have asked over at Meta: meta.stackexchange.com/q/290162/208995
– mike
Jan 23 '17 at 17:51
add a comment |
Paul's answer did not quite work. Modified code below which works for me on
windows 7 x64
vanilla CMD shell (eg, not git-bash or other non-M$ shell)
-- nothing
msvcrt
works in git-bash it appears.python 3.6
(I'm posting a new answer, because editing Paul's answer directly would change it from python 2.x-->3.x, which seems too much for an edit (py2 is still in use)
import sys, time, msvcrt
def readInput( caption, default, timeout = 5):
start_time = time.time()
sys.stdout.write('%s(%s):'%(caption, default))
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
byte_arr = msvcrt.getche()
if ord(byte_arr) == 13: # enter_key
break
elif ord(byte_arr) >= 32: #space_char
input += "".join(map(chr,byte_arr))
if len(input) == 0 and (time.time() - start_time) > timeout:
print("timing out, using default value.")
break
print('') # needed to move to next line
if len(input) > 0:
return input
else:
return default
# and some examples of usage
ans = readInput('Please type a name', 'john')
print( 'The name is %s' % ans)
ans = readInput('Please enter a number', 10 )
print( 'The number is %s' % ans)
formatting is not working as i expect here. I'm stumped, have asked over at Meta: meta.stackexchange.com/q/290162/208995
– mike
Jan 23 '17 at 17:51
add a comment |
Paul's answer did not quite work. Modified code below which works for me on
windows 7 x64
vanilla CMD shell (eg, not git-bash or other non-M$ shell)
-- nothing
msvcrt
works in git-bash it appears.python 3.6
(I'm posting a new answer, because editing Paul's answer directly would change it from python 2.x-->3.x, which seems too much for an edit (py2 is still in use)
import sys, time, msvcrt
def readInput( caption, default, timeout = 5):
start_time = time.time()
sys.stdout.write('%s(%s):'%(caption, default))
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
byte_arr = msvcrt.getche()
if ord(byte_arr) == 13: # enter_key
break
elif ord(byte_arr) >= 32: #space_char
input += "".join(map(chr,byte_arr))
if len(input) == 0 and (time.time() - start_time) > timeout:
print("timing out, using default value.")
break
print('') # needed to move to next line
if len(input) > 0:
return input
else:
return default
# and some examples of usage
ans = readInput('Please type a name', 'john')
print( 'The name is %s' % ans)
ans = readInput('Please enter a number', 10 )
print( 'The number is %s' % ans)
Paul's answer did not quite work. Modified code below which works for me on
windows 7 x64
vanilla CMD shell (eg, not git-bash or other non-M$ shell)
-- nothing
msvcrt
works in git-bash it appears.python 3.6
(I'm posting a new answer, because editing Paul's answer directly would change it from python 2.x-->3.x, which seems too much for an edit (py2 is still in use)
import sys, time, msvcrt
def readInput( caption, default, timeout = 5):
start_time = time.time()
sys.stdout.write('%s(%s):'%(caption, default))
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
byte_arr = msvcrt.getche()
if ord(byte_arr) == 13: # enter_key
break
elif ord(byte_arr) >= 32: #space_char
input += "".join(map(chr,byte_arr))
if len(input) == 0 and (time.time() - start_time) > timeout:
print("timing out, using default value.")
break
print('') # needed to move to next line
if len(input) > 0:
return input
else:
return default
# and some examples of usage
ans = readInput('Please type a name', 'john')
print( 'The name is %s' % ans)
ans = readInput('Please enter a number', 10 )
print( 'The number is %s' % ans)
edited Jan 23 '17 at 17:53
answered Jan 23 '17 at 17:33
mikemike
6091825
6091825
formatting is not working as i expect here. I'm stumped, have asked over at Meta: meta.stackexchange.com/q/290162/208995
– mike
Jan 23 '17 at 17:51
add a comment |
formatting is not working as i expect here. I'm stumped, have asked over at Meta: meta.stackexchange.com/q/290162/208995
– mike
Jan 23 '17 at 17:51
formatting is not working as i expect here. I'm stumped, have asked over at Meta: meta.stackexchange.com/q/290162/208995
– mike
Jan 23 '17 at 17:51
formatting is not working as i expect here. I'm stumped, have asked over at Meta: meta.stackexchange.com/q/290162/208995
– mike
Jan 23 '17 at 17:51
add a comment |
Following code worked for me.
I used two threads one to get the raw_Input and another to wait for a specific time.
If any of the thread exits, both the thread is terminated and returned.
def _input(msg, q):
ra = raw_input(msg)
if ra:
q.put(ra)
else:
q.put("None")
return
def _slp(tm, q):
time.sleep(tm)
q.put("Timeout")
return
def wait_for_input(msg="Press Enter to continue", time=10):
q = Queue.Queue()
th = threading.Thread(target=_input, args=(msg, q,))
tt = threading.Thread(target=_slp, args=(time, q,))
th.start()
tt.start()
ret = None
while True:
ret = q.get()
if ret:
th._Thread__stop()
tt._Thread__stop()
return ret
return ret
print time.ctime()
t= wait_for_input()
print "nResponse :",t
print time.ctime()
add a comment |
Following code worked for me.
I used two threads one to get the raw_Input and another to wait for a specific time.
If any of the thread exits, both the thread is terminated and returned.
def _input(msg, q):
ra = raw_input(msg)
if ra:
q.put(ra)
else:
q.put("None")
return
def _slp(tm, q):
time.sleep(tm)
q.put("Timeout")
return
def wait_for_input(msg="Press Enter to continue", time=10):
q = Queue.Queue()
th = threading.Thread(target=_input, args=(msg, q,))
tt = threading.Thread(target=_slp, args=(time, q,))
th.start()
tt.start()
ret = None
while True:
ret = q.get()
if ret:
th._Thread__stop()
tt._Thread__stop()
return ret
return ret
print time.ctime()
t= wait_for_input()
print "nResponse :",t
print time.ctime()
add a comment |
Following code worked for me.
I used two threads one to get the raw_Input and another to wait for a specific time.
If any of the thread exits, both the thread is terminated and returned.
def _input(msg, q):
ra = raw_input(msg)
if ra:
q.put(ra)
else:
q.put("None")
return
def _slp(tm, q):
time.sleep(tm)
q.put("Timeout")
return
def wait_for_input(msg="Press Enter to continue", time=10):
q = Queue.Queue()
th = threading.Thread(target=_input, args=(msg, q,))
tt = threading.Thread(target=_slp, args=(time, q,))
th.start()
tt.start()
ret = None
while True:
ret = q.get()
if ret:
th._Thread__stop()
tt._Thread__stop()
return ret
return ret
print time.ctime()
t= wait_for_input()
print "nResponse :",t
print time.ctime()
Following code worked for me.
I used two threads one to get the raw_Input and another to wait for a specific time.
If any of the thread exits, both the thread is terminated and returned.
def _input(msg, q):
ra = raw_input(msg)
if ra:
q.put(ra)
else:
q.put("None")
return
def _slp(tm, q):
time.sleep(tm)
q.put("Timeout")
return
def wait_for_input(msg="Press Enter to continue", time=10):
q = Queue.Queue()
th = threading.Thread(target=_input, args=(msg, q,))
tt = threading.Thread(target=_slp, args=(time, q,))
th.start()
tt.start()
ret = None
while True:
ret = q.get()
if ret:
th._Thread__stop()
tt._Thread__stop()
return ret
return ret
print time.ctime()
t= wait_for_input()
print "nResponse :",t
print time.ctime()
answered Mar 23 '17 at 12:22
MechatronMechatron
312
312
add a comment |
add a comment |
I spent a good twenty minutes or so on this, so I thought it was worth a shot to put this up here. It is directly building off of user137673's answer, though. I found it most useful to do something like this:
#! /usr/bin/env python
import signal
timeout = None
def main():
inp = stdinWait("You have 5 seconds to type text and press <Enter>... ", "[no text]", 5, "Aw man! You ran out of time!!")
if not timeout:
print "You entered", inp
else:
print "You didn't enter anything because I'm on a tight schedule!"
def stdinWait(text, default, time, timeoutDisplay = None, **kwargs):
signal.signal(signal.SIGALRM, interrupt)
signal.alarm(time) # sets timeout
global timeout
try:
inp = raw_input(text)
signal.alarm(0)
timeout = False
except (KeyboardInterrupt):
printInterrupt = kwargs.get("printInterrupt", True)
if printInterrupt:
print "Keyboard interrupt"
timeout = True # Do this so you don't mistakenly get input when there is none
inp = default
except:
timeout = True
if not timeoutDisplay is None:
print timeoutDisplay
signal.alarm(0)
inp = default
return inp
def interrupt(signum, frame):
raise Exception("")
if __name__ == "__main__":
main()
Great solution. Works very fine in Python3. Can't up-vote it enough.
– Regis May
Apr 25 '18 at 14:46
add a comment |
I spent a good twenty minutes or so on this, so I thought it was worth a shot to put this up here. It is directly building off of user137673's answer, though. I found it most useful to do something like this:
#! /usr/bin/env python
import signal
timeout = None
def main():
inp = stdinWait("You have 5 seconds to type text and press <Enter>... ", "[no text]", 5, "Aw man! You ran out of time!!")
if not timeout:
print "You entered", inp
else:
print "You didn't enter anything because I'm on a tight schedule!"
def stdinWait(text, default, time, timeoutDisplay = None, **kwargs):
signal.signal(signal.SIGALRM, interrupt)
signal.alarm(time) # sets timeout
global timeout
try:
inp = raw_input(text)
signal.alarm(0)
timeout = False
except (KeyboardInterrupt):
printInterrupt = kwargs.get("printInterrupt", True)
if printInterrupt:
print "Keyboard interrupt"
timeout = True # Do this so you don't mistakenly get input when there is none
inp = default
except:
timeout = True
if not timeoutDisplay is None:
print timeoutDisplay
signal.alarm(0)
inp = default
return inp
def interrupt(signum, frame):
raise Exception("")
if __name__ == "__main__":
main()
Great solution. Works very fine in Python3. Can't up-vote it enough.
– Regis May
Apr 25 '18 at 14:46
add a comment |
I spent a good twenty minutes or so on this, so I thought it was worth a shot to put this up here. It is directly building off of user137673's answer, though. I found it most useful to do something like this:
#! /usr/bin/env python
import signal
timeout = None
def main():
inp = stdinWait("You have 5 seconds to type text and press <Enter>... ", "[no text]", 5, "Aw man! You ran out of time!!")
if not timeout:
print "You entered", inp
else:
print "You didn't enter anything because I'm on a tight schedule!"
def stdinWait(text, default, time, timeoutDisplay = None, **kwargs):
signal.signal(signal.SIGALRM, interrupt)
signal.alarm(time) # sets timeout
global timeout
try:
inp = raw_input(text)
signal.alarm(0)
timeout = False
except (KeyboardInterrupt):
printInterrupt = kwargs.get("printInterrupt", True)
if printInterrupt:
print "Keyboard interrupt"
timeout = True # Do this so you don't mistakenly get input when there is none
inp = default
except:
timeout = True
if not timeoutDisplay is None:
print timeoutDisplay
signal.alarm(0)
inp = default
return inp
def interrupt(signum, frame):
raise Exception("")
if __name__ == "__main__":
main()
I spent a good twenty minutes or so on this, so I thought it was worth a shot to put this up here. It is directly building off of user137673's answer, though. I found it most useful to do something like this:
#! /usr/bin/env python
import signal
timeout = None
def main():
inp = stdinWait("You have 5 seconds to type text and press <Enter>... ", "[no text]", 5, "Aw man! You ran out of time!!")
if not timeout:
print "You entered", inp
else:
print "You didn't enter anything because I'm on a tight schedule!"
def stdinWait(text, default, time, timeoutDisplay = None, **kwargs):
signal.signal(signal.SIGALRM, interrupt)
signal.alarm(time) # sets timeout
global timeout
try:
inp = raw_input(text)
signal.alarm(0)
timeout = False
except (KeyboardInterrupt):
printInterrupt = kwargs.get("printInterrupt", True)
if printInterrupt:
print "Keyboard interrupt"
timeout = True # Do this so you don't mistakenly get input when there is none
inp = default
except:
timeout = True
if not timeoutDisplay is None:
print timeoutDisplay
signal.alarm(0)
inp = default
return inp
def interrupt(signum, frame):
raise Exception("")
if __name__ == "__main__":
main()
edited Oct 24 '14 at 20:52
answered Sep 16 '14 at 4:59
dylnmcdylnmc
2,02321328
2,02321328
Great solution. Works very fine in Python3. Can't up-vote it enough.
– Regis May
Apr 25 '18 at 14:46
add a comment |
Great solution. Works very fine in Python3. Can't up-vote it enough.
– Regis May
Apr 25 '18 at 14:46
Great solution. Works very fine in Python3. Can't up-vote it enough.
– Regis May
Apr 25 '18 at 14:46
Great solution. Works very fine in Python3. Can't up-vote it enough.
– Regis May
Apr 25 '18 at 14:46
add a comment |
Analogous to Locane's for windows:
import subprocess
subprocess.call('timeout /T 30')
2
If it matters, timeout was introduced with or after Windows Vista.
– DevPlayer
Sep 15 '16 at 12:43
add a comment |
Analogous to Locane's for windows:
import subprocess
subprocess.call('timeout /T 30')
2
If it matters, timeout was introduced with or after Windows Vista.
– DevPlayer
Sep 15 '16 at 12:43
add a comment |
Analogous to Locane's for windows:
import subprocess
subprocess.call('timeout /T 30')
Analogous to Locane's for windows:
import subprocess
subprocess.call('timeout /T 30')
edited Sep 8 '16 at 12:23
Petter Friberg
16k83774
16k83774
answered Sep 8 '16 at 12:23
Martijn van de DonkMartijn van de Donk
212
212
2
If it matters, timeout was introduced with or after Windows Vista.
– DevPlayer
Sep 15 '16 at 12:43
add a comment |
2
If it matters, timeout was introduced with or after Windows Vista.
– DevPlayer
Sep 15 '16 at 12:43
2
2
If it matters, timeout was introduced with or after Windows Vista.
– DevPlayer
Sep 15 '16 at 12:43
If it matters, timeout was introduced with or after Windows Vista.
– DevPlayer
Sep 15 '16 at 12:43
add a comment |
Here is a portable and simple Python 3 solution using threads.
This is the only one that worked for me while being cross-platform.
Other things I tried all had problems:
- Using signal.SIGALRM: not working on Windows
- Using select call: not working on Windows
- Using force-terminate of a process (instead of thread): stdin cannot be used in new process (stdin is auto-closed)
- Redirection stdin to StringIO and writing directly to stdin: will still write to previous stdin if input() has already been called (see https://stackoverflow.com/a/15055639/9624704)
from threading import Thread
class myClass:
_input = None
def __init__(self):
get_input_thread = Thread(target=self.get_input)
get_input_thread.daemon = True # Otherwise the thread won't be terminated when the main program terminates.
get_input_thread.start()
get_input_thread.join(timeout=20)
if myClass._input is None:
print("No input was given within 20 seconds")
else:
print("Input given was: ".format(myClass._input))
@classmethod
def get_input(cls):
cls._input = input("")
return
add a comment |
Here is a portable and simple Python 3 solution using threads.
This is the only one that worked for me while being cross-platform.
Other things I tried all had problems:
- Using signal.SIGALRM: not working on Windows
- Using select call: not working on Windows
- Using force-terminate of a process (instead of thread): stdin cannot be used in new process (stdin is auto-closed)
- Redirection stdin to StringIO and writing directly to stdin: will still write to previous stdin if input() has already been called (see https://stackoverflow.com/a/15055639/9624704)
from threading import Thread
class myClass:
_input = None
def __init__(self):
get_input_thread = Thread(target=self.get_input)
get_input_thread.daemon = True # Otherwise the thread won't be terminated when the main program terminates.
get_input_thread.start()
get_input_thread.join(timeout=20)
if myClass._input is None:
print("No input was given within 20 seconds")
else:
print("Input given was: ".format(myClass._input))
@classmethod
def get_input(cls):
cls._input = input("")
return
add a comment |
Here is a portable and simple Python 3 solution using threads.
This is the only one that worked for me while being cross-platform.
Other things I tried all had problems:
- Using signal.SIGALRM: not working on Windows
- Using select call: not working on Windows
- Using force-terminate of a process (instead of thread): stdin cannot be used in new process (stdin is auto-closed)
- Redirection stdin to StringIO and writing directly to stdin: will still write to previous stdin if input() has already been called (see https://stackoverflow.com/a/15055639/9624704)
from threading import Thread
class myClass:
_input = None
def __init__(self):
get_input_thread = Thread(target=self.get_input)
get_input_thread.daemon = True # Otherwise the thread won't be terminated when the main program terminates.
get_input_thread.start()
get_input_thread.join(timeout=20)
if myClass._input is None:
print("No input was given within 20 seconds")
else:
print("Input given was: ".format(myClass._input))
@classmethod
def get_input(cls):
cls._input = input("")
return
Here is a portable and simple Python 3 solution using threads.
This is the only one that worked for me while being cross-platform.
Other things I tried all had problems:
- Using signal.SIGALRM: not working on Windows
- Using select call: not working on Windows
- Using force-terminate of a process (instead of thread): stdin cannot be used in new process (stdin is auto-closed)
- Redirection stdin to StringIO and writing directly to stdin: will still write to previous stdin if input() has already been called (see https://stackoverflow.com/a/15055639/9624704)
from threading import Thread
class myClass:
_input = None
def __init__(self):
get_input_thread = Thread(target=self.get_input)
get_input_thread.daemon = True # Otherwise the thread won't be terminated when the main program terminates.
get_input_thread.start()
get_input_thread.join(timeout=20)
if myClass._input is None:
print("No input was given within 20 seconds")
else:
print("Input given was: ".format(myClass._input))
@classmethod
def get_input(cls):
cls._input = input("")
return
answered Jan 9 at 13:13
jorisv92jorisv92
111
111
add a comment |
add a comment |
Since this question seems to serve as a duplicate target, here the link to my accepted answer in a duplicate question.
Features
- Platform independent (Unix / Windows).
- StdLib only, no external dependencies.
- Threads only, no Subprocesses.
- Immediate interrupt at timeout.
- Clean shutdown of prompter at timeout.
- Unlimited inputs possible during time span.
- Easy expandable PromptManager class.
- Program may resume after timeout, multiple runs of prompter instances possible without program restart.
add a comment |
Since this question seems to serve as a duplicate target, here the link to my accepted answer in a duplicate question.
Features
- Platform independent (Unix / Windows).
- StdLib only, no external dependencies.
- Threads only, no Subprocesses.
- Immediate interrupt at timeout.
- Clean shutdown of prompter at timeout.
- Unlimited inputs possible during time span.
- Easy expandable PromptManager class.
- Program may resume after timeout, multiple runs of prompter instances possible without program restart.
add a comment |
Since this question seems to serve as a duplicate target, here the link to my accepted answer in a duplicate question.
Features
- Platform independent (Unix / Windows).
- StdLib only, no external dependencies.
- Threads only, no Subprocesses.
- Immediate interrupt at timeout.
- Clean shutdown of prompter at timeout.
- Unlimited inputs possible during time span.
- Easy expandable PromptManager class.
- Program may resume after timeout, multiple runs of prompter instances possible without program restart.
Since this question seems to serve as a duplicate target, here the link to my accepted answer in a duplicate question.
Features
- Platform independent (Unix / Windows).
- StdLib only, no external dependencies.
- Threads only, no Subprocesses.
- Immediate interrupt at timeout.
- Clean shutdown of prompter at timeout.
- Unlimited inputs possible during time span.
- Easy expandable PromptManager class.
- Program may resume after timeout, multiple runs of prompter instances possible without program restart.
edited Nov 13 '18 at 10:53
answered Nov 12 '18 at 16:25
DarkonautDarkonaut
3,2422821
3,2422821
add a comment |
add a comment |
A late answer :)
I would do something like this:
from time import sleep
print('Please provide input in 20 seconds! (Hit Ctrl-C to start)')
try:
for i in range(0,20):
sleep(1) # could use a backward counter to be preeety :)
print('No input is given.')
except KeyboardInterrupt:
raw_input('Input x:')
print('You, you! You know something.')
I know this is not the same but many real life problem could be solved this way. (I usually need timeout for user input when I want something to continue running if the user not there at the moment.)
Hope this at least partially helps. (If anyone reads it anyway :) )
1
No, KeyboardInterrupt exception occurs when users sends an interrupt signal, usually by hitting Ctrl+C on the terminal.
– Radian
Oct 31 '12 at 9:42
add a comment |
A late answer :)
I would do something like this:
from time import sleep
print('Please provide input in 20 seconds! (Hit Ctrl-C to start)')
try:
for i in range(0,20):
sleep(1) # could use a backward counter to be preeety :)
print('No input is given.')
except KeyboardInterrupt:
raw_input('Input x:')
print('You, you! You know something.')
I know this is not the same but many real life problem could be solved this way. (I usually need timeout for user input when I want something to continue running if the user not there at the moment.)
Hope this at least partially helps. (If anyone reads it anyway :) )
1
No, KeyboardInterrupt exception occurs when users sends an interrupt signal, usually by hitting Ctrl+C on the terminal.
– Radian
Oct 31 '12 at 9:42
add a comment |
A late answer :)
I would do something like this:
from time import sleep
print('Please provide input in 20 seconds! (Hit Ctrl-C to start)')
try:
for i in range(0,20):
sleep(1) # could use a backward counter to be preeety :)
print('No input is given.')
except KeyboardInterrupt:
raw_input('Input x:')
print('You, you! You know something.')
I know this is not the same but many real life problem could be solved this way. (I usually need timeout for user input when I want something to continue running if the user not there at the moment.)
Hope this at least partially helps. (If anyone reads it anyway :) )
A late answer :)
I would do something like this:
from time import sleep
print('Please provide input in 20 seconds! (Hit Ctrl-C to start)')
try:
for i in range(0,20):
sleep(1) # could use a backward counter to be preeety :)
print('No input is given.')
except KeyboardInterrupt:
raw_input('Input x:')
print('You, you! You know something.')
I know this is not the same but many real life problem could be solved this way. (I usually need timeout for user input when I want something to continue running if the user not there at the moment.)
Hope this at least partially helps. (If anyone reads it anyway :) )
answered Mar 14 '12 at 15:50
trytry
15
15
1
No, KeyboardInterrupt exception occurs when users sends an interrupt signal, usually by hitting Ctrl+C on the terminal.
– Radian
Oct 31 '12 at 9:42
add a comment |
1
No, KeyboardInterrupt exception occurs when users sends an interrupt signal, usually by hitting Ctrl+C on the terminal.
– Radian
Oct 31 '12 at 9:42
1
1
No, KeyboardInterrupt exception occurs when users sends an interrupt signal, usually by hitting Ctrl+C on the terminal.
– Radian
Oct 31 '12 at 9:42
No, KeyboardInterrupt exception occurs when users sends an interrupt signal, usually by hitting Ctrl+C on the terminal.
– Radian
Oct 31 '12 at 9:42
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1335507%2fkeyboard-input-with-timeout-in-python%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Is it OK if the solution works in Linux only?
– Nadia Alramli
Aug 26 '09 at 16:28
Yes, Linux only is fine.
– pupeno
Aug 27 '09 at 7:48
related: Python 3 Timed Input
– jfs
Oct 20 '14 at 2:44
possible duplicate of Timeout on a Python function call
– n611x007
Mar 13 '15 at 13:04
related: raw_input and timeout /3471461
– n611x007
Mar 13 '15 at 13:06