【问题标题】:python 3: subprocessing a python script that uses argparsepython 3:子处理使用 argparse 的 python 脚本
【发布时间】:2016-01-17 08:10:24
【问题描述】:

我为自己做了一个小实用程序“sa.py”,它可以从命令行运行。它调用 FFMPEG 来完成真正的工作。这个 sa.py 接受一些选项:

#! /usr/bin/env python3
# ...
import argparse
# ...
parser = argparse.ArgumentParser(description='...')
parser.add_argument(
    '--track',
    default='10m',
    dest='track',
    help="..."
)
# ...
args = parser.parse_args()

如果我自己运行 ./sa.py ,它工作正常(它正确地看到所有传递的命令行选项)。 当我尝试开发一个将 ./sa.py 作为子进程启动的 python GUI 时,麻烦就开始了。 gui 启动子进程,并且 sa.py 作为子进程正确执行,但这次命令行被忽略了,即使指定了。 无论您是否指定了不同的值,都将始终使用默认值(例如“--track”选项的“10m”)。

我说:./sa.py 本身可以正确处理它自己的命令行 但是 ./sa.py 在作为“GUI”python 脚本的子进程运行时将看不到命令​​行选项

所以问题集中在 sa_gui.pyw 中 subprocess.call 的使用上,但我猜不出问题出在哪里:

# this piece of code is included in a class on a python script
# that uses tk gui
# self.track, self.delta etc are all tkinter.StringVar() variables
# that you could change on the proper tkinter.Entry "widget"
cmd = [ os.path.realpath('./sa.py'),
        '--track', self.track.get(),
        '--delta', self.delta.get(),
        '--min', self.minimal.get(),
        '--balance', self.balance.get()]
# ...
subprocess.call(cmd, shell=True)

如果我调试“cmd”值,它会包含所需的所有信息:

  • (正确)要启动的 ./sa.py 脚本的位置
  • --轨道
  • [track_value]
  • --delta
  • [delta_value]

...等等。

所以我无法弄清楚问题出在哪里以及为什么在子处理购买 ./sa_gui.pyw 时 ./sa.py 会忽略命令行选项

有什么帮助吗?


搜索:

Not useful:这个问题与如何对python脚本进行子处理和实际使用的python版本有关。这里的问题集中在 subrprocessed python 脚本使用的 argparse 上

Not useful: 我不是在这里问如何从子进程捕获输出

Not useful: 同(2)原因

【问题讨论】:

  • shell=False有效果吗?
  • 它部分解决了这个问题,就像我对 Mike Muller 回答的评论中所解释的那样。谢谢:)

标签: python-3.x subprocess


【解决方案1】:

解决方案

我可以在 OSX 上重现您的问题:

subprocess.call(cmd, shell=True)

它在没有shell=True 的情况下工作:

subprocess.call(cmd)

测试代码

sa.py:

#! /usr/bin/env python3

import argparse
import sys


parser = argparse.ArgumentParser(description='...')
parser.add_argument(
    '--track',
    default='10m',
    dest='track',
    help="..."
)
args = parser.parse_args()
print(args)
print(sys.argv)

call_sa.py:

import os
import subprocess

cmd = [os.path.realpath('./sa.py'), '--track', '12']

print('shell False')
subprocess.call(cmd)
print()
print('shell True')
subprocess.call(cmd, shell=True)

输出:

python call_sa.py 
shell False
Namespace(track='12')
['/Users/mike/tmp/sa.py', '--track', '12']

shell True
Namespace(track='10m')
['/Users/mike/tmp/sa.py']

【讨论】:

  • 这个工作也在linux下。不幸的是,这不能在 Windows 上正常工作(我在微软自己合法提供的虚拟机上进行了测试)。所以恐怕不可能以多平台的方式正确地进行子处理。实际上,在 Windows 下,argparse 将被忽略(如果您设置 shell=True 和 shell=False ...如果您使用 shell=False,则需要将 sys.executable 添加到子进程命令列表中)。恐怕唯一的解决方案是启动子脚本,将其导入 GUI 脚本而不是子处理。但是,我希望我可以使用子流程。 ://
猜你喜欢
  • 1970-01-01
  • 2018-04-03
  • 2017-11-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
  • 2017-01-14
相关资源
最近更新 更多