【问题标题】:Workaround for timeout failure on subprocess.run?subprocess.run 超时失败的解决方法?
【发布时间】:2021-03-08 19:30:33
【问题描述】:

https://bugs.python.org/issue37424 有解决方法吗?

那个虫子在咬我。当我使用sudo apt install python3 安装时,我使用的是具有 Python 3.7.3 的 Raspberry Pi OS。

不幸的是,该错误仅在 Python 3.7.5 及更高版本中得到修复。

  • 在 Python 3.7.3 上是否有解决方法?
  • 如果没有,有人可以详细说明如何(我想,编译和)在 Raspberry Pi OS 上安装 Python 3.7.5(或更高版本)吗?我被告知它“复杂”并且可能会破坏其他东西(请参阅https://www.raspberrypi.org/forums/viewtopic.php?t=291158

我只需要超时工作。

FWIW,这是我的代码:

def command(string, verbose=None, echo_commands=ECHO_COMMANDS, timeout=SHORT_TIMEOUT):
    ''' Executes string as a command by the OS.
        Returns subprocess.CompletedProcess (stout, stderr, returncode, etc.).

        Note usual security precautions since shell=True (DO NOT use this with user input).
    '''

    if verbose is None:
        verbose = VERBOSE

    while True:
        try:
            if echo_commands:
                print("command:", string)

            cp = subprocess.run(string, shell=True, capture_output=True, text=True, timeout=timeout)

            if verbose:
                print(cp.stderr, cp.stdout)

            return cp

        except Exception as e:
            print(e)
            reboot_camera() #...and try again

【问题讨论】:

  • 您应该可以通过apt install python3.8(或其他方式)来获取特定版本。 apt search python3 会给你一个选项列表。
  • @Carcigenicate 唉,'apt search python3 | grep \'stable 3.8\'' 没有返回任何有用的东西(只是一些包)。

标签: python python-3.x raspberry-pi


【解决方案1】:

我找到了一个解决方案 - 使用 shell=False(然后超时工作)并使用 shlex.split 将命令解析为 Python 中的参数,而不是要求 shell 执行此操作。所以:

string = shlex.split(string) # workaround for https://bugs.python.org/issue37424 (plus shell=False instead of True)

cp = subprocess.run(string, shell=False, capture_output=True, text=True, timeout=timeout)

为了使其在 Windows 上也能正常工作,我不得不修改包含可执行文件名称的字符串以包含完整路径(好像 Windows 不搜索 $PATH 而没有 shell==True)。

旧:CHDKPTP_EXE = r'chdkptp'

新:CHDKPTP_EXE = r'c:\\bin\\chdkptp.bat'

【讨论】:

  • 除非绝对需要,否则不要使用shell=True,这非常罕见
  • @RyanHaining 我认为使用它没有任何问题,只要它没有(未经消毒的)用户输入。
  • 没有它就更容易获得正确的命令。尽管您对需要更精确的 Windows 查找是正确的,但 shutil.which('chdkptp') 可以为您获取完整路径。
猜你喜欢
  • 2012-05-10
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
相关资源
最近更新 更多