[ python-Bugs-1220113 ] subprocess call() helper should close stdin if PIPE
SourceForge.net
noreply at sourceforge.net
Wed Jun 22 10:45:21 CEST 2005
Bugs item #1220113, was opened at 2005-06-14 07:04
Message generated for change (Comment added) made by astrand
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1220113&group_id=5470
Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Closed
Resolution: Rejected
Priority: 5
Submitted By: Stuart Bishop (zenzen)
Assigned to: Peter Åstrand (astrand)
Summary: subprocess call() helper should close stdin if PIPE
Initial Comment:
The following code snippet should die instead of hang.
>>> from subprocess import call, PIPE
>>> rv = call(['/usr/bin/bzip2', '-c'], stdout=PIPE,
stdin=PIPE)
It makes no sense not to close stdin if it is PIPE
because the stream cannot be accessed.
The use case for this is ensuring a subprocess that
detects if it is connected to a terminal or not runs in
'batch' mode, and that it will die instead of hang if
it unexpectidly attempts to read from stdin.
Workaround is to use Popen instead.
----------------------------------------------------------------------
>Comment By: Peter Åstrand (astrand)
Date: 2005-06-22 10:45
Message:
Logged In: YES
user_id=344921
>Wanting to pass a closed file handle is common.
This is not my experience.
>It is needed when calling a program that behaves
differently if its stdin
>is a terminal or not.
Such programs are quite uncommon, and usually, it's a bad
idea to make such checks anyway.
>Or when you simply would prefer the subprocess to die if it
attempts to >read from its stdin rather than block
For this case, I would say that it's more common to pass
/dev/null than a closed file descriptor. It's uncommon with
shell scripts that does "someprogram <&4711". It's much more
common with "someprogram </dev/null". With subprocess, this
is already easy:
...stdin=open("/dev/null").
>Using Popen instead of call is s simpler workaround than
>creating and closing a file descriptor and passing it in.
How would you use Popen in this case?
>Perhaps what is needed is a new constant, subprocess.CLOSED
>which creates a new file descriptor and closes it? This
>would be useful for Popen too, allowing call() to remain a
>think and trivially documented wrapper?
It's not very hard to get an unused FD:
closed_fd = os.open("/dev/null", os.O_RDONLY);
os.close(closed_fd)
I'm a bit reluctant to add a new constant when you can solve
the problem anyway with one line of code.
Also, we'll need to think about the platform portability a
bit. Currently, I think that if we should add anything at
all, it should be a constant like subprocess.NULL, which
would be basically like open("/dev/null"), but also
portable to Windows.
----------------------------------------------------------------------
Comment By: Stuart Bishop (zenzen)
Date: 2005-06-22 08:12
Message:
Logged In: YES
user_id=46639
I can't think of any uses cases for wanting to create an
inaccessible pipe and give it to the child.
Wanting to pass a closed file handle is common. It is needed
when calling a program that behaves differently if its stdin
is a terminal or not. Or when you simply would prefer the
subprocess to die if it attempts to read from its stdin
rather than block.
Using Popen instead of call is s simpler workaround than
creating and closing a file descriptor and passing it in.
Perhaps what is needed is a new constant, subprocess.CLOSED
which creates a new file descriptor and closes it? This
would be useful for Popen too, allowing call() to remain a
think and trivially documented wrapper?
----------------------------------------------------------------------
Comment By: Peter Åstrand (astrand)
Date: 2005-06-21 18:08
Message:
Logged In: YES
user_id=344921
>It makes no sense not to close stdin if it is PIPE
>because the stream cannot be accessed
True, but what if you actually *want* to create an
inaccessible pipe, and give it to the child?
Currently, the call() wrapper is *very* short and simple. I
think this is very good. For example, it allows us to
document it in two sentences. You get what you ask for: If
you use call() with strange arguments, you'll get a somewhat
strange behavíour. I see no point in introducing lots of
sanity checks in the wrapper functions.
>The use case for this is ensuring a subprocess that
>detects if it is connected to a terminal or not runs in
>batch' mode, and that it will die instead of hang if
>it unexpectidly attempts to read from stdin
I'm not sure I understand what you want, but if you want to
have stdin connected to a closed file descriptor, just pass one:
>>> from subprocess import call, PIPE
>>> rv = call(['/usr/bin/bzip2', '-c'], stdout=PIPE,
stdin=4711)
(Of course, you should verify that 4711 is unused.)
If you don't agree with me, post to python-dev for discussion.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1220113&group_id=5470
More information about the Python-bugs-list
mailing list