How to Listen to Stdin Input Without Pausing My Script

How do I listen to STDIN input without pausing my script?

Not sure where are the commands you want to "continue running" in your example. Try this small script:

Thread.new do
loop do
s = gets.chomp
puts "You entered #{s}"
exit if s == 'end'
end
end

i = 0
loop do
puts "And the script is still running (#{i})..."
i += 1
sleep 1
end

Reading from STDIN is done in a separate thread, while the main script continues to work.

Input without stopping program

Here's a function that will timeout if no input is given:

import select
import sys

def timeout_input(timeout, prompt="", timeout_value=None):
sys.stdout.write(prompt)
sys.stdout.flush()
ready, _, _ = select.select([sys.stdin], [], [], timeout)
if ready:
return sys.stdin.readline().rstrip('\n')
else:
sys.stdout.write('\n')
sys.stdout.flush()
return timeout_value

You can easily modify it so it shows the remaining time by changing the timeout value on select.select to 1, and looping timeout times.

Bash input without pausing the script?

read -t0 can be used to probe for input if your process is structured as a loop

 #!/bin/bash

a='\|/-'
spin()
{
sleep 0.3
a="${a:1}${a:0:1}"
echo -n $'\e'7$'\r'"${a:1:1}"$'\e'8
}

echo 'try these /|\- , dbpq , |)>)|(<( , =>-<'

echo -n " enter a pattern to spin:"
while true
do
spin
if read -t0
then
read a
echo -n " using $a enter a new pattern:"
fi
done

else you could run one command in the background while promptiong for input in the foreground. etc...

Capture characters from standard input without waiting for enter to be pressed

That's not possible in a portable manner in pure C++, because it depends too much on the terminal used that may be connected with stdin (they are usually line buffered). You can, however use a library for that:

  1. conio available with Windows compilers. Use the _getch() function to give you a character without waiting for the Enter key. I'm not a frequent Windows developer, but I've seen my classmates just include <conio.h> and use it. See conio.h at Wikipedia. It lists getch(), which is declared deprecated in Visual C++.

  2. curses available for Linux. Compatible curses implementations are available for Windows too. It has also a getch() function. (try man getch to view its manpage). See Curses at Wikipedia.

I would recommend you to use curses if you aim for cross platform compatibility. That said, I'm sure there are functions that you can use to switch off line buffering (I believe that's called "raw mode", as opposed to "cooked mode" - look into man stty). Curses would handle that for you in a portable manner, if I'm not mistaken.

Get user input without assuming there is a question

If you don't want to use an empty string for rl.question, you could simply listen on the line event as you don't even have to prompt the user with a question at all:

const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

rl.on('line', (line) => {
console.log(`You typed ${line}`);
});

From the docs:

The 'line' event is emitted whenever the input stream receives an
end-of-line input (\n, \r, or \r\n). This usually occurs when the user
presses Enter or Return.

The listener function is called with a string containing the single
line of received input.

Non-blocking console input?

For Windows, console only, use the msvcrt module:

import msvcrt

num = 0
done = False
while not done:
print(num)
num += 1

if msvcrt.kbhit():
print "you pressed",msvcrt.getch(),"so now i will quit"
done = True

For Linux, this article describes the following solution, it requires the termios module:

import sys
import select
import tty
import termios

def isData():
return select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], [])

old_settings = termios.tcgetattr(sys.stdin)
try:
tty.setcbreak(sys.stdin.fileno())

i = 0
while 1:
print(i)
i += 1

if isData():
c = sys.stdin.read(1)
if c == '\x1b': # x1b is ESC
break

finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)

For cross platform, or in case you want a GUI as well, you can use Pygame:

import pygame
from pygame.locals import *

def display(str):
text = font.render(str, True, (255, 255, 255), (159, 182, 205))
textRect = text.get_rect()
textRect.centerx = screen.get_rect().centerx
textRect.centery = screen.get_rect().centery

screen.blit(text, textRect)
pygame.display.update()

pygame.init()
screen = pygame.display.set_mode( (640,480) )
pygame.display.set_caption('Python numbers')
screen.fill((159, 182, 205))

font = pygame.font.Font(None, 17)

num = 0
done = False
while not done:
display( str(num) )
num += 1

pygame.event.pump()
keys = pygame.key.get_pressed()
if keys[K_ESCAPE]:
done = True

Ruby get input only if input exists

This works but only because self.reload! is not called while my console window is selected

Thread.new do
loop do
script_temp = gets
@script = @script + script_temp
end
end

def self.reload!
begin
eval @script
$stdout.flush()
rescue Exception
end
@script = ''
end

Based on this

Pause script until user presses enter in Node.JS

You can simply take input from stdin
Sample function :

function waitForKey(keyCode) {
return new Promise(resolve => {
process.stdin.on('data',function (chunk) {
if (chunk[0] === keyCode) {
resolve();
process.stdin.pause();
}
});
});
}

Now if you want to wait for enter key :

await waitForKey(10);

How can I test whether stdin has input available in julia?

bytesavailable(stdin)

Here is a sample usage. Note that if you capture the keyboard you also need to handle Ctrl+C yourself (in this example only the first byte of chunk is checked).

If you want to run it fully asynchronously put @async in front of the while loop. However if there will be no more code in this case this program will just exit.

import REPL
term = REPL.Terminals.TTYTerminal("xterm",stdin,stdout,stderr)
REPL.Terminals.raw!(term,true)
Base.start_reading(stdin)

while (true)
sleep(1)
bb = bytesavailable(stdin)
if bb > 0
data = read(stdin, bb)
if data[1] == UInt(3)
println("Ctrl+C - exiting")
exit()
end
println("Got $bb bytes: $(string(data))")
end
end


Related Topics



Leave a reply



Submit