detect if sys.stdin is ... - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: detect if sys.stdin is ... (/thread-10606.html) |
detect if sys.stdin is ... - Skaperen - May-28-2018 how to detect if sys.stdin is the controlling tty (as opposed to a pipe, or a socket, or a file, or "/dev/null", or some other tty the script was invoked to read from)? is there an equivalent in windows? RE: detect if sys.stdin is ... - ljmetzger - May-30-2018 Results depend on the 'stdin_encoding' Codec values which are probably dependent on location (e.g. United States) and/or encoding directive (line 2 - line after Shebang). A one size fits all algorithm can probably be obtained after testing various locations and default encodings. I was able to detect the following on Python 3.6.5 using Windows 10 in the United States 'stdin' as: a. Keyboard b. Null Device c. Redirected file (but not the file name) d. Pipe Function get_stdin_encoding() seems to work OK. Other functions are for reference purposes and seem to fail when 'stdin' is the NULL DEVICE. # Tested using Python 3.6.5 on Windows 10 # # Reference: https://python-forum.io/Thread-detect-if-sys-stdin-is # Reference: https://stackoverflow.com/questions/323829/how-to-find-out-if-there-is-data-to-be-read-from-stdin-on-windows-in-python # Reference: https://stackoverflow.com/questions/13442574/how-do-i-determine-if-sys-stdin-is-redirected-from-a-file-vs-piped-from-another # Reference: https://docs.python.org/3/library/os.html # NOTE: os.ttyname(sys.stdin.fileno()) is NOT available on Windows # Reference: https://docs.python.org/3/library/codecs.html (Codec values in section 7.2.3 Standard Encodings) ################################## ################################## #NOTE: The only method that seems to work on Windows is get_stdin_encoding(). # The other methods FAIL when stdin is the NULL DEVICE ################################## ################################## import os import stat import sys def is_stdin_keyboard(): #NOTE: This returns INCORRECT results when 'stdin' is the NULL DEVICE return os.isatty( sys.stdin.fileno()) def get_stdin_from_stat(): #NOTE: this function is NOT USED - incorporated into get_stdin_encoding() mode = os.fstat(0).st_mode if stat.S_ISFIFO(mode): return 'Pipe' elif stat.S_ISREG(mode): return 'Redirected' else: return 'Keyboard' def get_stdin_encoding(): # NOTE: Results depend on the 'stdin_encoding' values which are probably dependent # on location (e.g. United States) and/or encoding directive (line 2 - line after Shebang). # See https://docs.python.org/3/library/codecs.html (Codec values in section 7.2.3 Standard Encodings) stdin_encoding = getattr(sys, 'stdin').encoding if stdin_encoding == 'cp437': stdin_source = 'Null Device' elif stdin_encoding == 'cp1252': #return 'file or pipe' mode = os.fstat(0).st_mode if stat.S_ISFIFO(mode): stdin_source = 'Pipe' else: stdin_source = 'Redirected' elif stdin_encoding == 'utf-8': stdin_source = 'Keyboard' else: stdin_source = 'Encoding=' + stdin_encoding return stdin_source + " (" + stdin_encoding + ")" print("get_stdin_encoding() results: Stdin device type is: {}.".format(get_stdin_encoding())) if is_stdin_keyboard(): print("is_stdin_keyboard() results: Stdin is the Keyboard") else: print("is_stdin_keyboard() results: Stdin is NOT the Keyboard") print("sys.stdin.isatty() results: {}".format(sys.stdin.isatty()))The following Windows cmd.exe script was used to test the code (e.g. file abc.bat): NOTE: The follow is NOT Python code but a Windows .bat file @echo off echo Testing stdin >ScratchStdOut.txt echo. >>ScratchStdOut.txt echo ###################### >>ScratchStdOut.txt echo Testing 'Keyboard' stdin >>ScratchStdOut.txt python redirectStdin-001.py >>ScratchStdOut.txt echo ###################### >>ScratchStdOut.txt echo Testing 'Null Device' stdin >>ScratchStdOut.txt python redirectStdin-001.py >>ScratchStdOut.txt <nul echo ###################### >>ScratchStdOut.txt rem NOTE: Windows prevents this from running if the redirected 'stdin' file DOES NOT EXIST rem This creates and deletes file 'Scratch00.txt' echo Testing 'Redirected' File stdin >>ScratchStdOut.txt echo Hello >Scratch00.txt python redirectStdin-001.py >>ScratchStdOut.txt <Scratch00.txt if exist Scratch00.txt del Scratch00.txt echo ###################### >>ScratchStdOut.txt echo Testing 'Pipe' stdin >>ScratchStdOut.txt echo hello | python redirectStdin-001.py >>ScratchStdOut.txt echo ###################### >>ScratchStdOut.txt type ScratchStdOut.txt pause exitResults using the .bat file: LewisAdded .zip file attachment containing: a. RedirectStdin-001.bat b. RedirectStdin-001.py RE: detect if sys.stdin is ... - Skaperen - May-30-2018 i have a script that modifies its stdin input and outputs it. the nature of the script has no value to typing in directly from the terminal where it was started. what i want to do is detect that it was run with no input and output a message and quit. RE: detect if sys.stdin is ... - ljmetzger - May-30-2018 The following was tested on Python 3.6.5 using Windows 10 in the United States: # Tested using Python 3.6.5 on Windows 10 in the United States # # Reference: https://python-forum.io/Thread-detect-if-sys-stdin-is import sys if sys.stdin.isatty(): print ("Do Nothing - stdin is either 'tty' or 'null device'.") else: print ("Process 'stdin' from 'pipe' or from 'file redirection'.") for i, dataline in enumerate(sys.stdin, start=1): print(i, dataline)The following Windows cmd.exe script was used to test the code (e.g. file abc.bat): NOTE: The follow is NOT Python code but a Windows .bat file @echo off echo Testing stdin >ScratchStdOut.txt echo. >>ScratchStdOut.txt echo ###################### >>ScratchStdOut.txt echo Testing 'Keyboard' stdin >>ScratchStdOut.txt python redirectStdin-002.py >>ScratchStdOut.txt echo ###################### >>ScratchStdOut.txt echo Testing 'Null Device' stdin >>ScratchStdOut.txt python redirectStdin-002.py >>ScratchStdOut.txt <nul echo ###################### >>ScratchStdOut.txt rem NOTE: Windows prevents this from running if the redirected 'stdin' file DOES NOT EXIST rem This creates and deletes file 'Scratch00.txt' echo Testing 'Redirected' File stdin >>ScratchStdOut.txt echo Hello >Scratch00.txt echo World >>Scratch00.txt python redirectStdin-002.py >>ScratchStdOut.txt <Scratch00.txt if exist Scratch00.txt del Scratch00.txt echo ###################### >>ScratchStdOut.txt echo Testing 'Pipe' stdin >>ScratchStdOut.txt echo Pipe stdin text - Hello World | python redirectStdin-002.py >>ScratchStdOut.txt echo ###################### >>ScratchStdOut.txt type ScratchStdOut.txt pause exitResults using the .bat file: See the .zip file attachment containing:a. RedirectStdin-002.bat b. RedirectStdin-002.py Lewis RE: detect if sys.stdin is ... - Skaperen - May-30-2018 but if the user runs this program to read from some other tty (that may be a controlling tty for other processes) besides his own (e.g is not this process' controlling tty) then i want it to treat that as valid input. so the test needs to be "is my stdin the same devive as my controlling tty." i don't expect to be able to resolve program < /dev/tty vs. program .
|