在参数中运行带引号的命令可以使用commands.getoutput(),但不能运行子进程模块

时间:2017-02-09 16:11:00

标签: python python-2.7 subprocess

我正在创建一个调用许多其他程序和脚本的python程序(在Unix(SUNos)+ Linux上)。除了1个脚本,我正在使用子进程。

我不使用子进程的脚本是perl脚本,它已被制作成可执行文件。不知怎的,它不允许我使用子进程,但它适用于(不赞成)命令包。 我想理解为什么它不能用于子进程(换句话说:我做错了什么;-))

(实际的perl命令并不重要,但会返回用户的全名和电子邮件)

我尝试了什么:

PERL_CMD = [ '<executable perl-script>', '-rt', '"users"', '-eq', '"name"' '"<user_name>", '-fs', '":"', '-fld', '"fullname"', '"email"' ]
full_name, email = subprocess.check_output( PERL_CMD ).split(':')

但这不起作用。

命令变体可行的地方:

PERL_CMD = '<executable perl-script> -rt "users" -eq "name" "<user_name>" -fs ":" -fld "full_name" "email"'
full_name, email = commands.getoutput( PERL_CMD ).split(':')

有人知道为什么我不能让子进程工作吗?

令我讨厌的是,我可以让它为除此之外的所有事情工作(尽管我有一个可接受的(但已弃用的)解决方法)。

1 个答案:

答案 0 :(得分:1)

您在commands.getoutput()案例中使用了语法引用,在subprocess.check_output()案例中使用了字面引号。没有shell=True(你不应该使用),没有shell可以解析引号作为语法,所以除了引号之外没有语法引用这样的东西。语法到Python本身

所以,只需取出你注入参数的"

# this contains quotes that are syntactic to Python only, and no literal quotes
perl_cmd = [
  '<executable perl-script>',
  '-rt', 'users',
  '-eq', 'name', '<user_name>',
  '-fs', ':',
  '-fld', 'fullname', 'email' ]

详细解释一下 -

当您将"name"作为命令的一部分传递给shell时,引用在其解析过程中由shell本身消耗,而不是作为参数传递给命令。因此,当您运行sh -c 'echo "hello"'时,会将完全相同的参数传递给echo sh -c 'echo hello'; echo命令甚至无法区分两次调用之间的差异!

相反,当您将'"hello"'作为参数传递给subprocess.Popen()时,外部引号被Python使用,内部引号作为文字传递给内部命令。这使它等同于sh -c 'echo "\"hello\""'(同样将字面引号传递给echo),而不是sh -c 'echo "hello"'(不是HttpServletRequest request = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()); request.getLocalAddr(); request.getLocalPort();