Python Forum
Thread Rating:
  • 1 Vote(s) - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
detect if sys.stdin is ...
#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: 188)
To paraphrase: 'Throw out your dead' code. https://www.youtube.com/watch?v=grbSQ6O6kbs Forward to 1:00
Reply


Messages In This Thread
detect if sys.stdin is ... - by Skaperen - May-28-2018, 03:34 AM
RE: detect if sys.stdin is ... - by ljmetzger - May-30-2018, 04:10 AM
RE: detect if sys.stdin is ... - by Skaperen - May-30-2018, 06:39 AM
RE: detect if sys.stdin is ... - by ljmetzger - May-30-2018, 01:18 PM
RE: detect if sys.stdin is ... - by Skaperen - May-30-2018, 11:49 PM

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 1,098 Sep-24-2022, 05:06 PM
Last Post: Gribouillis
  STDIN not working H84Gabor 3 3,771 Sep-06-2021, 08:10 AM
Last Post: H84Gabor
  How to read a file using stdin? pyth0nus3r 1 2,920 Aug-24-2019, 01:14 AM
Last Post: Larz60+
  What is the sys.stdin.isatty() command? pyth0nus3r 2 11,742 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 3,002 Jul-23-2019, 11:50 AM
Last Post: Birju_Barot
  is it safe to close stdin Skaperen 1 2,753 Apr-04-2019, 06:57 AM
Last Post: Gribouillis
  Need help with reading input from stdin into array list Annie123 2 5,165 Mar-24-2019, 01:19 PM
Last Post: Annie123
  storing lines from stdin in a list bghosh 2 3,101 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,248 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