我正在创建一个调用许多其他程序和脚本的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(':')
有人知道为什么我不能让子进程工作吗?
令我讨厌的是,我可以让它为除此之外的所有事情工作(尽管我有一个可接受的(但已弃用的)解决方法)。
答案 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();
。