1

Trying to differentiate if stdout is going to pipe or process substitution.

my_python_script.py

#!/usr/bin/python3.6
if sys.__stdin__.isatty():
    print("__stdin__ is TTY")
else:
    print("__stdin__ is not TTY")
if sys.__stdout__.isatty():
    print("__stdout__ is TTY")
else:
    print("__stdout__ is not TTY")
if sys.__stderr__.isatty():
    print("__stderr__ is TTY")
else:
    print("__stderr__ is not TTY")

if sys.stdin.isatty():
    print("stdin is TTY")
else:
    print("stdin is not TTY")
if sys.stdout.isatty():
    print("stdout is TTY")
else:
    print("stdout is not TTY")
if sys.stderr.isatty():
    print("stderr is TTY")
else:
    print("stderr is not TTY")

The output below is identical if pipe or process substitution.

> my_python_script.py | cat

__stdin__ is TTY
__stdout__ is not TTY
__stderr__ is TTY
stdin is TTY
stdout is not TTY
stderr is TTY

> cat <(my_python_script.py)

__stdin__ is TTY
__stdout__ is not TTY
__stderr__ is TTY
stdin is TTY
stdout is not TTY
stderr is TTY

Is there a way to differentiate between output to a pipe vs. process substitution inside a python script?

Thank you

0

2 Answers 2

1

Following script should differentiate two cases :

import os
import re
import sys

def get_fds(id):
    fds = [os.path.realpath(f"/proc/{id}/fd/{i}") 
           for i in list(os.walk(f'/proc/{id}/fd'))[0][2]]
    return [re.sub('.*/', '', i) 
            for i in fds if "pipe" in i]

if  any(i == j for i in get_fds(os.getpid())
               for j in get_fds(os.getppid())):
    print("Process substitution", file=sys.stderr)
else:
    print("Normal pipe", file=sys.stderr)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. Just tried it and seems to work. Will test it a bit more and also break it up to understand what exactly your code is doing.
0

The process subsitiution creates a named pipe.

$ echo <(uptime)
/dev/fd/63

$ file <(uptime)
/dev/fd/63: broken symbolic link to pipe:[11474138]

So the answer is NO.

1 Comment

Bash only uses named pipes/fifos for process substitution when the OS doesn't support the /dev/fd pseudo-filesystem. That's just the /dev/fd entry for the read end of an anonymous pipe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.