Python Forum
Thread Rating:
  • 1 Vote(s) - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
detect if sys.stdin is ...
#1
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?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
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
exit
Results using the .bat file:
Output:
Testing stdin ###################### Testing 'Keyboard' stdin get_stdin_encoding() results: Stdin device type is: Keyboard (utf-8). is_stdin_keyboard() results: Stdin is the Keyboard sys.stdin.isatty() results: True ###################### Testing 'Null Device' stdin get_stdin_encoding() results: Stdin device type is: Null Device (cp437). is_stdin_keyboard() results: Stdin is the Keyboard sys.stdin.isatty() results: True ###################### Testing 'Redirected' File stdin get_stdin_encoding() results: Stdin device type is: Redirected (cp1252). is_stdin_keyboard() results: Stdin is NOT the Keyboard sys.stdin.isatty() results: False ###################### Testing 'Pipe' stdin get_stdin_encoding() results: Stdin device type is: Pipe (cp1252). is_stdin_keyboard() results: Stdin is NOT the Keyboard sys.stdin.isatty() results: False ######################
Lewis

Added .zip file attachment containing:
a. RedirectStdin-001.bat
b. RedirectStdin-001.py

Attached Files

.zip   RedirectStdin-001.zip (Size: 1.47 KB / Downloads: 179)
To paraphrase: 'Throw out your dead' code. https://www.youtube.com/watch?v=grbSQ6O6kbs Forward to 1:00
Reply
#3
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.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
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
exit
Results using the .bat file:
Output:
Testing stdin ###################### Testing 'Keyboard' stdin Do Nothing - stdin is either 'tty' or 'null device'. ###################### Testing 'Null Device' stdin Do Nothing - stdin is either 'tty' or 'null device'. ###################### Testing 'Redirected' File stdin Process 'stdin' from 'pipe' or from 'file redirection'. 1 Hello 2 World ###################### Testing 'Pipe' stdin Process 'stdin' from 'pipe' or from 'file redirection'. 1 Pipe stdin text - Hello World ######################
See the .zip file attachment containing:
a. RedirectStdin-002.bat
b. RedirectStdin-002.py

Lewis

Attached Files

.zip   RedirectStdin-002.zip (Size: 845 bytes / Downloads: 194)
To paraphrase: 'Throw out your dead' code. https://www.youtube.com/watch?v=grbSQ6O6kbs Forward to 1:00
Reply
#5
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.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  When is stdin not connected to a tty, but can still be used interactively? stevendaprano 1 967 Sep-24-2022, 05:06 PM
Last Post: Gribouillis
  STDIN not working H84Gabor 3 3,429 Sep-06-2021, 08:10 AM
Last Post: H84Gabor
  How to read a file using stdin? pyth0nus3r 1 2,796 Aug-24-2019, 01:14 AM
Last Post: Larz60+
  What is the sys.stdin.isatty() command? pyth0nus3r 2 11,272 Aug-22-2019, 04:37 PM
Last Post: pyth0nus3r
  getting error "exec_proc.stdin.write(b'yes\n') IOError: [Errno 32] Broken pipe" Birju_Barot 0 2,903 Jul-23-2019, 11:50 AM
Last Post: Birju_Barot
  is it safe to close stdin Skaperen 1 2,616 Apr-04-2019, 06:57 AM
Last Post: Gribouillis
  Need help with reading input from stdin into array list Annie123 2 4,999 Mar-24-2019, 01:19 PM
Last Post: Annie123
  storing lines from stdin in a list bghosh 2 2,952 May-02-2018, 01:12 PM
Last Post: gruntfutuk
  How can I use GNU readline when the value of sys.stdin has been changed? thePhysicist8 6 7,002 Dec-30-2016, 10:09 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020