本文介绍了在参数中运行带引号的命令适用于 commands.getoutput() 但不适用于 subprocess 模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 python 程序,它调用许多其他程序和脚本(在 Unix(SUNos) + Linux 上).除了 1 个脚本之外,我在任何地方都使用子进程.

I'm creating a python program that calls a number of other programs and scripts (on Unix(SUNos) + Linux). I'm using subprocess everywhere except for 1 script.

我不使用子进程的脚本是一个 perl 脚本,它已被制作成可执行文件.不知何故,它不允许我使用子进程,但它可以与(不推荐使用的)命令包一起使用.我想了解为什么它不适用于子流程(换句话说:我做错了什么;-))

The script for which I don't use subprocess is a perl-script which has been made into an executable. Somehow it does not let me use subprocess on, but it works with the (deprecated) commands package.I would like to understand why it does not work with subprocess (in other words: what am I doing wrong ;-) )

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

(What the actual perl command is not important, but it returns the full name and email of a user as result)

我尝试了什么:

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

但这不起作用.

命令变体起作用的地方:

Where the commands variant does work:

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

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

Has anybody an idea why I can't get subprocess to work?

令我烦恼的是,我可以让它在除此之外的所有情况下工作(尽管我有一个可接受(但已弃用)的解决方法).

It is annoying me that I can get it to work for everything except this (eventhough I have an acceptable (but deprecated) workaround).

推荐答案

您在 commands.getoutput() 案例中使用语法引号,在 subprocess.check_output 中使用文字引号() 案例.如果没有 shell=True(你不应该使用),就没有 shell 将引号解析为语法,所以没有语法引号这样的东西,除了语法toPython 本身.

You're using syntactic quotes in the commands.getoutput() case, and literal quotes in the subprocess.check_output() case. Without shell=True (which you shouldn't use), there's no shell to parse quotes as syntax, so there's no such thing as a syntactic quote, other than the quotes that are syntax to Python itself.

因此,只需取出您注入参数的 " 即可:

So, just take out the "s that you injected into your arguments:

# 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' ]

再详细解释一下 --


To explain a bit more detail --

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

When you pass "name" to a shell as part of a command, the quotes are consumed by the shell itself during its parsing process, not passed to the command as an argument. Thus, when you run sh -c 'echo "hello"', this passes the exact same argument to echo as sh -c 'echo hello'; the echo command can't even tell the difference between the two invocations!

当您将 '"hello"' 作为参数传递给 subprocess.Popen() 时,相比之下,Python 会使用外引号,内引号作为文字传递给内部命令.这使得它等效于 sh -c 'echo "\"hello\""'(同样将文字引号传递给 echo),而不是 sh -c'echo "hello"'(没有).

When you pass '"hello"' as an argument to subprocess.Popen(), by contrast, the outer quotes are consumed by Python, and the inner quotes are passed as literal to the inner command. That makes it equivalent to sh -c 'echo "\"hello\""' (which likewise passes literal quotes through to echo), not sh -c 'echo "hello"' (which does not).

这篇关于在参数中运行带引号的命令适用于 commands.getoutput() 但不适用于 subprocess 模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 15:47