我正在尝试使用subprocess.Popen()镜像以下shell命令:
echo "SELECT employeeid FROM Users WHERE samaccountname=${1};" | bsqldb -S mdw2k8sqlp02.dow.com -D PhoneBookClient -U PortManUser -P plum45\\torts -q
目前看起来像:
stdout = subprocess.Popen(["echo", "\"SELECT", "employeeid", "FROM", "Users", "WHERE", "samaccountname=${1};\"", "|", "bsqldb", "arg1etc"], stdout=subprocess.PIPE)
for line in stdout.stdout.readlines():
print line
看来这是错误的,它会返回以下标准:
"SELECT employeeid FROM Users WHERE samaccountname=${1};" | bsqldb arg1etc
有谁知道我的subprocess.Popen()语法出错了吗?
答案 0 :(得分:1)
问题是您尝试在没有shell的情况下运行shell命令。发生的事情是你传递所有这些字符串 - 包括"|"
以及作为echo
命令的参数之后的所有内容。
只需在您的通话中添加shell=True
即可解决问题。
但是,您几乎肯定希望将命令行作为字符串传递,而不是试图猜测将连接回字符串以传递给shell的列表。
或者,更好的是,不要使用shell,而是在Python中管道。文档中包含Replacing shell pipeline代码的{{3}}(以及各种其他内容)。{/ p>
但是在你的情况下,你试图管道的东西只是subprocess
,这是非常愚蠢的,因为你已经确切地知道echo
会返回什么,并且可以将它作为输入第二个程序。
另外,我不确定您希望echo
填写的内容。大概是你正在移植一个shell脚本,它在命令行上带了一些参数;你的Python脚本可能在${1}
中有相同的东西,但如果不了解你正在做的事情,那就不过是一个猜测。
答案 1 :(得分:0)
Python中echo some string | command arg1 arg2
shell管道的类比是:
from subprocess import Popen, PIPE
p = Popen(["command", "arg1", "arg2"], stdin=PIPE)
p.communicate("some string")
在您的情况下,您可以将其写为:
import shlex
import sys
from subprocess import Popen, PIPE
cmd = shlex.split("bsqldb -S mdw2k8sqlp02.dow.com -D PhoneBookClient "
"-U PortManUser -P plum45\\torts -q")
sql = """SELECT employeeid FROM Users
WHERE samaccountname={name};""".format(name=sql_escape(sys.argv[1]))
p = Popen(cmd, stdin=PIPE)
p.communicate(input=sql)
sys.exit(p.returncode)