How to find out if there is data to be read from stdin on Windows in Python?

This code

select.select([sys.stdin], [], [], 1.0)

does exactly what I want on Linux, but not in Windows.

I've used kbhit() in msvcrt before to see if data is available on stdin for reading, but in this case it always returns 0. Additionally msvcrt.getch() returns '\xff' whereas sys.stdin.read(1) returns '\x01'. It seems as if the msvcrt functions are not behaving properly.

Unfortunately I can't use TCP sockets as I'm not in control of the application talking my Python program.


Asked by: Lily767 | Posted: 30-11-2021






Answer 1

In some rare situations, you might care what stdin is connected to. Mostly, you don't care -- you just read stdin.

In someprocess | python myprogram.py, stdin is connected to a pipe; in this case, the stdout of the previous process. You simply read from sys.stdin and you're reading from the other process. [Note that in Windows, however, there's still (potentially) a "CON" device with a keyboard. It just won't be sys.stdin.]

In python myprogram.py <someFile, stdin is connected to a file. You simply read from sys.stdin and you're reading from the file.

In python myprogram.py, stdin is left connected to the console (/dev/ttyxx in *nix). You simple read from sys.stdin and you're reading from the keyboard.

Note the common theme in the above three cases. You simply read from sys.stdin and your program's environment defines everything for you. You don't check "to see if data is available on stdin for reading". It's already available.

Sometimes, you want a keyboard interrupt (or other shenanigans). Python, BTW, has a keyboard interrupt as a first-class feature of the I/O elements. Control-C raises an interrupt during I/O (it won't break into a tight loop, but it will signal a program that prints periodically.)

Sometimes you need to find out what kind of file stdin is connected to.

Something like os.isatty( sys.stdin.fileno() ) If sys.stdin is a TTY, you're program was left connected to the windows "CON" (the keyboard). If sys.stdin is not a TTY, it's connected to a file or a pipe.


Example

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\slott>python
Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import sys
>>> os.isatty( sys.stdin.fileno() )
True
>>>

The value of True tells me Python is running without a file or pipe attached. sys.stdin is the keyboard. Using windows kbhit is needless.

A value of False tells me Python is running with a file or pipe attached. sys.stdin is NOT the keyboard. Checking kbhit might be meaningful. Also, I could open the CON: device and read the keyboard directly, separate from sys.stdin.


I'm not sure why you need "to see if data is available on stdin for reading". It might help to update your question with additional details of what you're trying to accomplish.

Answered by: Brooke230 | Posted: 01-01-2022



Answer 2

I run a thread that reads from stdin, then forward the data to a socket. The socket is selectable, so, stdin is selectable too.

In a recent project, I must continuously read from one network socket, forward to another socket, until the user inputs q from the console. One may think to use threading, but I don’t want to deal with multi-thread stuffs. Finally, I found a none-clear solution, and it worked.

I create one thread – YES, thread, but no multi-thread concerns – this thread open a server socket listening on random port, then open a client socket connect to this server. The server socket accept the connection, then call sys.stdin.read() in a block way, all data read from stdin will write to that accepted connection. So client socket receive data reading from stdin. Now, the client socket is a selectable stdin, and it is thread-safe.

Source code:

# coding=UTF-8
""" === Windows stdio ===
@author ideawu@163.com
@link http://www.ideawu.net/
File objects on Windows are not acceptable for select(),
this module creates two sockets: stdio.s_in and stdio.s_out,
as pseudo stdin and stdout.

@example
from stdio import stdio
stdio.write('hello world')
data = stdio.read()
print stdio.STDIN_FILENO
print stdio.STDOUT_FILENO
"""
import thread
import sys, os
import socket

# socket read/write in multiple threads may cause unexpected behaviors
# so use two separated sockets for stdin and stdout

def __sock_stdio():
    def stdin_thread(sock, console):
        """ read data from stdin, and write the data to sock
        """
        try:
            fd = sys.stdin.fileno()
            while True:
                # DO NOT use sys.stdin.read(), it is buffered
                data = os.read(fd, 1024)
                #print 'stdin read: ' + repr(data)
                if not data:
                    break
                while True:
                    nleft = len(data)
                    nleft -= sock.send(data)
                    if nleft == 0:
                        break
        except:
            pass
        #print 'stdin_thread exit'
        sock.close()

    def stdout_thread(sock, console):
        """ read data from sock, and write to stdout
        """
        try:
            fd = sys.stdout.fileno()
            while True:
                data = sock.recv(1024)
                #print 'stdio_sock recv: ' + repr(data)
                if not data:
                    break
                while True:
                    nleft = len(data)
                    nleft -= os.write(fd, data)
                    if nleft == 0:
                        break
        except:
            pass
        #print 'stdin_thread exit'
        sock.close()


    class Console:
        def __init__(self):
            self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.serv.bind(('127.0.0.1', 0))
            self.serv.listen(5)
            port = self.serv.getsockname()[1]

            # data read from stdin will write to this socket
            self.stdin_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.stdin_sock.connect(('127.0.0.1', port))
            self.s_in, addr = self.serv.accept()
            self.STDIN_FILENO = self.s_in.fileno()
            thread.start_new_thread(stdin_thread, (self.stdin_sock, self))

            # data read from this socket will write to stdout
            #self.stdout_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            #self.stdout_sock.connect(('127.0.0.1', port))
            #self.s_out, addr = self.serv.accept()
            #self.STDOUT_FILENO = self.s_out.fileno()
            #thread.start_new_thread(stdout_thread, (self.stdout_sock, self))

            self.read_str = '' # read buffer for readline

        def close(self):
            self.s_in.close()
            self.s_out.close()
            self.stdin_sock.close()
            self.stdout_sock.close()
            self.serv.close()

        def write(self, data):
            try:
                return self.s_out.send(data)
            except:
                return -1

        def read(self):
            try:
                data = self.s_in.recv(4096)
            except:
                return ''
            ret = self.read_str + data
            self.read_str = ''
            return ret

        def readline(self):
            while True:
                try:
                    data = self.s_in.recv(4096)
                except:
                    return ''
                if not data:
                    return ''
                pos = data.find('\n')
                if pos == -1:
                    self.read_str += data
                else:
                    left = data[0 : pos + 1]
                    right = data[pos + 1 : ]
                    ret = self.read_str + left
                    self.read_str = right
                    return ret

    stdio = Console()
    return stdio

def __os_stdio():
    class Console:
        def __init__(self):
            self.STDIN_FILENO = sys.stdin.fileno()
            self.STDOUT_FILENO = sys.stdout.fileno()

        def close(self):
            pass

        def write(self, data):
            try:
                return os.write(self.STDOUT_FILENO, data)
            except:
                return -1

        def read(self):
            try:
                return os.read(self.STDIN_FILENO, 4096)
            except:
                return ''

        def readline(self):
            try:
                return sys.stdin.readline()
            except:
                return ''

    stdio = Console()
    return stdio

if os.name == 'posix':
    stdio = __os_stdio()
else:
    stdio = __sock_stdio()

Answered by: Melissa143 | Posted: 01-01-2022



Similar questions

Can you open stdin as a file on MS Windows in Python?

On Linux, I'm using supbprocess.Popen to run an app. The command line of that app requires a path to an input file. I learned I can pass the path /dev/stdin to the command line, and then use Python's subproc.stdin.write() to send input to the subprocess. import subprocess kw['shell'] = False kw['executable'] = '/path/to/myapp' kw['stdin'] = subprocess.PIPE kw['stdout'] = subprocess.PIPE kw['stderr'] = subpr...


windows - Using DPAPI with Python?

Is there a way to use the DPAPI (Data Protection Application Programming Interface) on Windows XP with Python? I would prefer to use an existing module if there is one that can do it. Unfortunately I haven't been able to find a way with Google or Stack Overflow. EDIT: I've taken the example code pointed to by "dF" and tweaked it into a standalone library which can be simply used at a high ...


Python script - SCP on windows

How is it possible to do secure copy using python (windows native install - ActivePython). Unfortunately pexpect module is for unix only and we don't want cygwin locally. I wrote a script that based on pscp.exe win tool - but always stops at first execution becuse of fingerprint host id. and haven't found option to switch this off. the remote hosts are running ssh-server on cygwin (win 2003 servers). Thanks


windows - How to set up Python in a web server?

Not exactly about programming, but I need help with this. I'm running a development sever with WampServer. I want to install Python (because I prefer to use Python over PHP), but it seems there isn't an obvious choice. I've read about mod_python and WSGI, and about how the latter is better. However, from what I gathered (I may be wrong) you have to do more low-level stuff with WSGI than with PHP. So I resea...


how to parse windows inf files for python?

please help me. example inf file : ;============================================================================= ; ; Copyright (c) Intel Corporation (2002). ; ; INTEL MAKES NO WARRANTY OF ANY KIND REGARDING THE CODE. THIS CODE IS ; LICENSED ON AN "AS IS" BASIS AND INTEL WILL NOT PROVIDE ANY SUPPORT, ; ASSISTANCE, INSTALLATION, TRAINING OR OTHER SERVICES. INTEL DOES NOT ; PROVIDE ANY UPDATES, ENHANCEMENT...


How to setup twill for python 2.6 on Windows?

I have already downloaded twill 0.9. Also, I have installed easy_install for python 2.6. Now I'm stuck with twill installation. Could you help me to settle the problem?


windows - How To: View MFC Doc File in Python

I want to use Python to access MFC document files generically? Can CArchive be used to query a file and view the structure, or does Python, in opening the document, need to know more about the document structure in order to view the contents?


How to set proxy in Windows with Python?

How can I get the current Windows' browser proxy setting, as well as set them to a value? I know I can do this by looking in the registry at Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer, but I'm looking, if it is possible, to do this without messing directly with the registry.


how to run both python 2.6 and 3.0 on the same windows XP box?

What kind of setup do people use to run both python 2.6 and python 3.0 on the same windows machine?


Python 2.6.2, Django 1.0.3, Windows XP, Page not found: /

I'm just starting to learn Python and Django and an unable to get the most basic app working. I've setup Python, added python to the Path environment variable, installed Django using install.py script. I created an app by running the command django-admin.py startproject my_project updated the settings.py file for a database DATABASE_ENGINE = 'sqlite3' DATABASE_NAME...


Using the Python shell in Vi mode on Windows

I know that you can use the Python shell in Vi mode on Unix-like operating systems. For example, I have this line in my ~/.inputrc: set editing-mode vi This lets me use Vi-style editing inside the Python shell. But can this be made to work when using Python on a Windows XP box? I'm using the pre-built Python for Windows downloaded directly from python.org. I'm ...


windows - Create an icon in memory with win32 in python

What's a good way to generate an icon in-memory in python? Right now I'm forced to use pygame to draw the icon, then I save it to disk as an .ico file, and then I load it from disk as an ICO resource... Something like this: if os.path.isfile(self.icon): icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE hicon = win32gui.LoadImage(hinst, ...


windows xp - Process size in XP from Python

I have a python script that can approach the 2 GB process limit under Windows XP. On a machine with 2 GB physical memory, that can pretty much lock up the machine, even if the Python script is running at below normal priority. Is there a way in Python to find out my own process size? Thanks, Gerry


How can I read system information in Python on Windows?

Following from this OS-agnostic question, specifically this response, similar to data available from the likes of /proc/meminfo on Linux, how can I read system information from Windows using Python (including, but...


In the windows python console, how to make Tab = four spaces?

Hello I would like that when I am in the python console tabbing will give me four spaces. Any ideas?


windows xp - Cygwin and Python 2.6

New to python (and programming). What exactly do I need from Cygwin? I'm running python 2.6 on winxp. Can I safely download the complete Cygwin? It just seems like a huge bundle of stuff. Well, I keep running into modules and functionality (i.e. piping output) which suggest downloading various cygwin components. Will cygwin change or modify any other os functionality or have any other side effects?


windows - Using DPAPI with Python?

Is there a way to use the DPAPI (Data Protection Application Programming Interface) on Windows XP with Python? I would prefer to use an existing module if there is one that can do it. Unfortunately I haven't been able to find a way with Google or Stack Overflow. EDIT: I've taken the example code pointed to by "dF" and tweaked it into a standalone library which can be simply used at a high ...


windows - How do I create a webpage with buttons that invoke various Python scripts on the system serving the webpage?

I'm a hobbyist (and fairly new) programmer who has written several useful (to me) scripts in python to handle various system automation tasks that involve copying, renaming, and downloading files amongst other sundry activities. I'd like to create a web page served from one of my systems that would merely present a few buttons which would allow me to initiate these scripts remotely. The problem is that I do...


How do I create a windows service with Python


Python script - SCP on windows

How is it possible to do secure copy using python (windows native install - ActivePython). Unfortunately pexpect module is for unix only and we don't want cygwin locally. I wrote a script that based on pscp.exe win tool - but always stops at first execution becuse of fingerprint host id. and haven't found option to switch this off. the remote hosts are running ssh-server on cygwin (win 2003 servers). Thanks


windows - Example of how to use msilib to create a .msi file from a python module

Can anyone give me an example of how to use python's msilib standard library module to create a msi file from a custom python module? For example, let's say I have a custom module called cool.py with the following code class Cool(object): def print_cool(self): print &quot;cool&quot; and I wa...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top