为什么在python2.7中使用subprocess.check_output(shell = true)会导致挂起?

发布于 2025-02-04 22:09:43 字数 1755 浏览 2 评论 0原文

代码

b.py中的

# b.py
import subprocess
from sys import stdout

cmd = ['python2.7','a.py']

try: 
    subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError as e:
    print 'cmd:', e.cmd, 'end'
    print 'output:', e.output,'end'
    print 'returncode:', e.returncode, 'end'

print 'ok'

在a.py中

# a.py
import sys

print 'a.py'
sys.stderr.write('stderr\n')
sys.stdout.write('stdout\n')

exit(-1)

,我

称呼python2.7 b.py,它停止了,就好像在等待输入一样。

我键入ctrl-c后,追溯是:

/home/liweiming/app/test〉python2.7  b.py                                                                                                                                                                                                                 06/07/2022 11:25:07 AM
^CTraceback (most recent call last):
  File "b.py", line 10, in <module>
    subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
  File "/usr/lib/python2.7/subprocess.py", line 217, in check_output
    output, unused_err = process.communicate()
  File "/usr/lib/python2.7/subprocess.py", line 475, in communicate
    stdout = _eintr_retry_call(self.stdout.read)
  File "/usr/lib/python2.7/subprocess.py", line 125, in _eintr_retry_call
    return func(*args)
KeyboardInterrupt

但是,如果我使用subprocess.check_output(shell = false),则该程序很好。

Code

in b.py

# b.py
import subprocess
from sys import stdout

cmd = ['python2.7','a.py']

try: 
    subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError as e:
    print 'cmd:', e.cmd, 'end'
    print 'output:', e.output,'end'
    print 'returncode:', e.returncode, 'end'

print 'ok'

in a.py

# a.py
import sys

print 'a.py'
sys.stderr.write('stderr\n')
sys.stdout.write('stdout\n')

exit(-1)

What I do

after I call python2.7 b.py, it stopped, as if waiting for input.
enter image description here

after I type ctrl-c, the traceback is:

/home/liweiming/app/test〉python2.7  b.py                                                                                                                                                                                                                 06/07/2022 11:25:07 AM
^CTraceback (most recent call last):
  File "b.py", line 10, in <module>
    subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
  File "/usr/lib/python2.7/subprocess.py", line 217, in check_output
    output, unused_err = process.communicate()
  File "/usr/lib/python2.7/subprocess.py", line 475, in communicate
    stdout = _eintr_retry_call(self.stdout.read)
  File "/usr/lib/python2.7/subprocess.py", line 125, in _eintr_retry_call
    return func(*args)
KeyboardInterrupt

But if I use subprocess.check_output(shell=False), the program is well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拒绝两难 2025-02-11 22:09:43

使用shell = true命令变为['sh','-c','python2.7','a.py'] - 此通过a.py作为sh的参数(大致忽略了 - 在交互式脚本中将其设置为$ 0,但这没关系,因为该脚本只是python2.7) - 然后运行python2.7

因为该命令仍将其附加到终端上,因此它将等待输入(就像交互式解释器一样) - 例如,尝试键入1 + 1&lt; enter&gt;&lt;^d&gt;,并且您将获得输出(从Interactive python2.7本身)

绝对是一个怪异的行为,我宁愿希望命令为列表 + shell = true会引起typeError(要求命令是字符串) - 但可惜

以下是shell = true行为的示例将位置参数传递给外壳字符串:

>>> subprocess.check_output(['echo $0 $1', 'hello', 'world'], shell=True)
b'hello world\n'

with shell=True the command becomes ['sh', '-c', 'python2.7', 'a.py'] -- this passes a.py as an argument to sh (which is roughly ignored -- it's set as $0 in the interactive script but it doesn't matter because that script is just python2.7) -- this then runs python2.7

since that command is still attached to the terminal, it will wait for input (as the interactive interpreter does) -- try for instance typing 1 + 1<enter><^D> and you'll get output back (from the interactive python2.7 itself)

definitely a weird behaviour, I would've rather hoped that command being a list + shell=True would raise a TypeError (requiring the command to be a string) -- but alas

here's an example of the shell=True behaviour passing positional arguments to the shell string:

>>> subprocess.check_output(['echo $0 $1', 'hello', 'world'], shell=True)
b'hello world\n'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文