【问题标题】:Python subprocess.call with argsPython subprocess.call 带参数
【发布时间】:2012-06-12 21:21:54
【问题描述】:

我正在尝试使用带有 args 的 python subprocess.call 来调用 shell 脚本。我所拥有的 args 没有被传递给 shell 脚本,但是脚本被调用没有问题。这就是我所拥有的

prepend = str(prepend)
print "prepend = " + str(prepend)
filename = str(request.FILES['mdbfile'])
print "filename = " + str(filename)
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
print "PROJECT_ROOT = " + str(PROJECT_ROOT)
filename = str(PROJECT_ROOT) + '/%s' % filename
print "full_filename = " + str(filename)
cmd = '%s/buildcsvs.sh' % (PROJECT_ROOT)
print "full_cmd = " + str(cmd)
p = subprocess.call([cmd, filename, prepend], shell=True)
output = p.stdout.read()
print output

Shell 脚本如下所示

#${1} is the file name, ${2} is the prepend code
echo "mdb-export ${1} TEAM > \"${2}team.csv\""
mdb-export ${1} TEAM > "${2}team.csv"

这是输出的样子

prepend = 749176818
filename = 2011ROXBURY.mdb
PROJECT_ROOT = /Planner
full_filename = /Planner/2011ROXBURY.mdb
full_cmd = /Planner/buildcsvs.sh
Exception AttributeError: AttributeError("'_DummyThread' object has no attribute   '_Thread__block'",) in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored
mdb-export  TEAM > "team.csv"
Usage: mdb-export [options] <file> <table>

有人知道我做错了什么吗?谢谢 - 感谢您的帮助

编辑:现在,我有这个:

print "full_cmd = " + str(cmd)
args = "%s %s" % (filename, prepend)
print "full_args = " + str(args)
(out, err) = Popen(cmd,  stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True).communicate(args)

它看起来并没有成功完成对脚本的调用。

你知道为什么吗?

【问题讨论】:

标签: python django shell subprocess


【解决方案1】:

如果你通过shell=True args 必须是字符串而不是列表:

In [4]: from subprocess import check_output

In [5]: check_output(['echo', '123'])
Out[5]: '123\n'

In [6]: check_output(['echo', '123'], shell=True)
Out[6]: '\n'

In [7]: check_output('echo 123', shell=True)
Out[7]: '123\n'

编辑:您应该使用Popen().communicate,而不是使用callp.stdout.read,这是为此目的而设计的,它有助于避免死锁。

Edit²(上面的编辑答案):

cmd = ' '.join([cmd, args])
(out, err) = Popen(cmd,  stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True, shell=True).communicate(None)

您必须将完整的命令行传递给Popencommunicate 的参数将被写入 process.stdinprocess = Popen 返回的内容)。

【讨论】:

  • 谢谢——希望这能解决我遇到的异常。我已经更新了帖子,但仍然遇到问题
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多