Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed4.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.005 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'output': 0.05; '"""': 0.07; 'amounts': 0.07; 'problem?': 0.07; 'string': 0.09; 'none)': 0.09; 'subject:()': 0.09; "system's": 0.09; '24,': 0.16; 'blocking': 0.16; 'fully,': 0.16; 'looping': 0.16; 'process?': 0.16; 'received:mail-wi0-f178.google.com': 0.16; 'stderr': 0.16; 'stdout': 0.16; 'variations': 0.16; 'skip:# 20': 0.16; 'ignore': 0.16; 'wrote:': 0.18; 'hey': 0.18; '(but': 0.19; 'written': 0.21; 'seems': 0.21; 'memory': 0.22; 'select': 0.22; 'example': 0.22; 'import': 0.22; 'issue.': 0.22; 'to:name:python-list@python.org': 0.22; 'print': 0.22; '(such': 0.24; 'possibly': 0.26; 'header:In- Reply-To:1': 0.27; 'message-id:@mail.gmail.com': 0.30; 'code': 0.31; 'pipe': 0.31; 'produces': 0.31; 'work:': 0.31; 'probably': 0.32; 'received:209.85.212': 0.32; 'cases': 0.33; 'could': 0.34; 'received:209.85': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'method': 0.36; 'should': 0.36; 'too': 0.37; 'received:209': 0.37; 'being': 0.38; 'writes': 0.38; 'to:addr :python-list': 0.38; 'issue': 0.38; 'pm,': 0.38; 'rather': 0.38; 'that,': 0.38; 'skip:. 10': 0.39; 'sure': 0.39; 'to:addr:python.org': 0.39; 'enough': 0.39; 'either': 0.39; 'skip:p 20': 0.39; 'how': 0.40; 'read': 0.60; 'then,': 0.60; 'more': 0.64; 'due': 0.66; 'here': 0.66; 'close': 0.67; 'mar': 0.68; 'attention': 0.75; 'filling': 0.78; 'potentially': 0.81; '2015': 0.84; 'vulnerable': 0.84; 'provide,': 0.91 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:content-type; bh=i4qQxrtXuW1MyvUJCQvW2XfYXmYmHoe7bUe2slj/+F4=; b=R6TqFi66/uC6lMl2LV3ww5R7gQCwd7dfAwKvc3QFNw31NM9Bp+Q7jdJL7qb0awNFHL F8E9y15ZXMZd/kET0BWMT5uOBy7ny3Z2m3ciREdGWVsu8TOWeBe3jojygLzrRyZBpGYp qxQC9cAyZBExkLaSkONHnBKtDAXCsfY20V3I81gh50QRutIOwfCnjkJo5/z6g6O4GKL9 9MD78UiiYyOHLyx0lihqI0bWuU1fq/qDDvZ8AL0ZFRi1QLf/sdYk/Hn6FA8CjFxeWoqV nvXP31COm6NGAmm7gub5Qh21EuwjEfWxhMbobj82qjv1vN7hWB4TyXza6qT0eBXb7Vnr Ew6Q== X-Gm-Message-State: ALoCoQnT4mZZzWHcPB22RbUOtyrfc3nWUnvoLAxRhjBQhYoGLy52oybYCgZiqRjPklGm9QdhurgB X-Received: by 10.181.8.103 with SMTP id dj7mr31371300wid.75.1427226758395; Tue, 24 Mar 2015 12:52:38 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: From: Chris Kaynor Date: Tue, 24 Mar 2015 12:52:18 -0700 Subject: Re: subprocess and stdin.write(), stdout.read() To: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.19 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 71 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1427226765 news.xs4all.nl 2853 [2001:888:2000:d::a6]:35018 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:87902 On Tue, Mar 24, 2015 at 12:08 PM, Tobiah wrote: > The docs for the subprocess.Popen() say: > > Use communicate() rather than .stdin.write, .stdout.read > or .stderr.read to avoid deadlocks due to any of the other > OS pipe buffers filling up and blocking the child process > > But if I want to send a string to stdin, how can I do that without > stdin.write()? > > This seems to work: > > import subprocess as s > > thing = """ > hey > there > foo man is here > hey foo > man is there > so foo > """ > p = s.Popen(['grep', 'foo'], stdin = s.PIPE, stdout = s.PIPE) > p.stdin.write(thing) > print p.communicate() > > ###################### > > ('\they foo\n \tfoo there\n', None) > > > Will this always avoid the deadlock problem? What you should do is use "print p.communicate(thing)". That will always avoid the deadlock issue. Your code MAY deadlock in some cases as the stdin pipe could fill up fully, but the other process is not reading it as it is waiting for you to read output. What this means is that, you must be reading from stdout AND stderr if you are possibly waiting for the process (such as when writing to stdin or using .wait() or looping on .poll()). subprocess.communicate() takes care of that issue internally, however you can write your own variations (useful if you need to process stdout to produce stdin, for example), however you must either be using a select or threads to be sure to be reading stdout and stderr. You should also pay attention to the note on communicate - if potentially large amounts of data will be produced, you may need to write your own method to avoid memory paging/OOM issues due to communicate filling up the system's RAM. In the example you provide, you will probably never hit the deadlock as the data being written is small enough that it should never fill the buffers (typically, they are ~2k). Additionally, if you know the process never produces output on stdout or stderr, you can ignore them (but then, why would you pipe them?). > > This also works: > > p = s.Popen(['grep', 'foo'], stdin = s.PIPE, stdout = s.PIPE) > p.stdin.write(thing) > p.stdin.close() > print p.stdout.read() > > Is that vulnerable to deadlock? Is there a better way > to write to and read from the same process? This is more likely to cause deadlocks as, if the process writes too much to stderr, it may stall waiting for you to read it, while you are waiting for it to close stdout.