简体   繁体   English

subprocess.Popen错误

[英]subprocess.Popen error

I am running an msi installer in silent mode and caching logs in the specific file. 我在静默模式下运行msi安装程序并在特定文件中缓存日志。 The following is the command i need to execute. 以下是我需要执行的命令。

C:\\Program Files\\ My Installer\\Setup.exe /s /v "/qn /lv %TEMP%\\log_silent.log"

I used: 我用了:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]

to execute the command however it does not recognise the operation and gives error regarding wrong option selected. 执行命令然而它无法识别操作并且在选择错误选项时给出错误。 I have cross-verified and found that the command only works this way. 我已经交叉验证,发现命令只能这样工作。

The problem is very subtle. 问题非常微妙。

You're executing the program directly. 你正在直接执行该程序。 It gets: 它得到:

argv[0] = "C:\Program Files\ My Installer\Setup.exe"
argv[1] = /s /v "/qn /lv %TEMP%\log_silent.log"

Whereas it should be: 它应该是:

argv[1] = "/s"
argv[2] = "/v"
argv[3] = "/qn"
argv[4] = "/lv %TEMP%\log_silent.log"

In other words, it should receive 5 arguments, not 2 arguments. 换句话说,它应该接收5个参数,而不是2个参数。

Also, %TEMP% is directly unknown to the program! 此外, %TEMP%直接在程序中未知!

There are 2 ways to fix this problem: 有两种方法可以解决此问题:

  1. Calling the shell. 调用shell。

     p = subprocess.Popen('C:\\Program Files\\ My Installer\\Setup.exe /s /v "/qn /lv %TEMP%\\log_silent.log"', shell=True) output = p.communicate()[0] 
  2. Directly call program (more safer) 直接打电话给程序(更安全)

     s = ['C:\\Program Files\\ My Installer\\Setup.exe', '/s /v "/qn /lv %TEMP%\\log_silent.log"'] safes = [os.path.expandvars(p) for p in argument_string] p = subprocess.Popen(safes[0], safes[1:]) output = p.communicate()[0] 

The problem is that you effectively supply Setup.exe with only one argument. 问题是您有效地为Setup.exe提供了一个参数。 Don't think in terms of the shell, the string you hand over as an argument does not get splitted on spaces anymore, that's your duty! 不要以shell的形式来思考,你作为参数交出的字符串不会再被分隔在空格上,这是你的职责!

So, if you are absolutely sure that "/qn /lv %TEMP%\\log_silent.log" should be one argument, then use this: 所以,如果你绝对确定“/ qn / lv%TEMP%\\ log_silent.log”应该是一个参数,那么使用这个:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn /lv %TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]

Otherwise (I guess this one will be correct), use this: 否则(我想这个会是正确的),使用这个:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s', '/v', '/qn', '/lv', '%TEMP%\log_silent.log'],stdout=subprocess.PIPE).communicate()[0]

Try putting each argument in its own string (reformatted for readability): 尝试将每个参数放在自己的字符串中(为了便于阅读,重新格式化):

cmd = ['C:\Program Files\ My Installer\Setup.exe',
       '/s',
       '/v',
       '"/qn',
       '/lv',
       '%TEMP%\log_silent.log"']

subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]

I have to say though, those double quotes do not look in the right places to me. 我不得不说,那些双引号并不适合我。

You said: 你说:

subprocess.Popen(['C:\Program Files\ My Installer\Setup.exe', '/s /v "/qn /lv %TEMP%\log_silent.log"'],stdout=subprocess.PIPE).communicate()[0]

Is the directory name really " My Installer" (with a leading space)? 目录名称是否真的是“我的安装程序”(带有前导空格)?

Also, as a general rule, you should use forward slashes in path specifications. 此外,作为一般规则,您应该在路径规范中使用正斜杠。 Python should handle them seamlessly (even on Windows) and you avoid any problems with python interpreting backslashes as escape characters. Python应该无缝地处理它们(甚至在Windows上)并且你可以避免python将反斜杠解释为转义字符的任何问题。

(for example: (例如:

>>> s = 'c:\program files\norton antivirus'
>>> print s
c:\program files
orton antivirus

)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM