python加双引号报错 'C:\Program' is not recognized

下面代码中的变量 content 加上双引号就报错,不知道为什么。

import os
chrome = r'"C:\Program Files\Google\Chrome\Application\chrome.exe"'

content='a b c'.replace(' ', '%20')

cmd = chrome + ' --args --new-window https://baidu.com?wd={content}'
cmd1 = f'{chrome} --args --new-window https://baidu.com?wd={content}'
cmd2 = f'{chrome} --args --new-window https://baidu.com/s?wd="{content}"'  # error

# "C:\Program Files\Google\Chrome\Application\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"
print(cmd2)

# os.system(cmd)  # ok
# os.system(cmd1) # ok
# os.system(cmd2) # error

# os.system(f'{chrome} --args --new-window https://baidu.com/s?wd={content}')  # ok
os.system(f'{chrome} --args --new-window https://baidu.com/s?wd="{content}"')  # error
# os.system(f'{chrome} --args --new-window https://baidu.com/s?wd=\"{content}\"')  # error
# os.system(f"{chrome} --args --new-window https://baidu.com/s?wd=\"{content}\"")  # error


#os.system(r'"C:\Program Files\Google\Chrome\Application\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"') # error
#os.system(r'C:\Program Files\Google\Chrome\Application\chrome.exe --args --new-window https://baidu.com/s?wd="a%20b%20c"')   # error

输出:

C:\cygwin64\home\god\bin\test\test>python test1.py
"C:\Program Files\Google\Chrome\Application\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

cmd2 的输出是 "C:\Program Files\Google\Chrome\Application\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c" 这个在 cmd 下可以直接运行,但是放到 os.system(cmd2) 中就报错。

再举例:

>>> cmd2 = '"C:\Program Files\Google\Chrome\Application\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"'
>>> os.system(cmd2)
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
1

# wd 后面的参数不加双引号就正常了,但是下面这个在编译后运行时报错,必须给 cmd2 后面的字符串加上 r'"C:\Pro......"' 再次编译运行才正常
>>> cmd2 =  '"C:\Program Files\Google\Chrome\Application\chrome.exe" --args --new-window https://baidu.com/s?wd=a%20b%20c'
>>> os.system(cmd2)
0
>>>

想知道为什么。

阅读 3.1k
2 个回答

问题比较有趣,正如你提到的,如果你直接把 cmd 打印的内容在 cmd 执行,是可以执行的。

但是这并不代表实际是可行的,在 Windows 上,文档中是这样说的:

On Windows, the return value is that returned by the system shell after running command. The shell is given by the Windows environment variable COMSPEC: it is usually cmd.exe, which returns the exit status of the command run; on systems using a non-native shell, consult your shell documentation.

也就是说,实际上看起来应该是像这样运行的

cmd /k "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"

如果你拷贝这段到 cmd 执行,你就会发现你会得到一个一模一样的输出,即 C:\Program 命令不存在

现在在 cmd 上执行 cmd /?

你会看到一段文字

如果指定了 /C 或 /K,则会将该开关之后的
命令行的剩余部分作为一个命令行处理,其中,会使用下列逻辑
处理引号(")字符:

    1.  如果符合下列所有条件,则会保留
        命令行上的引号字符:

        - 不带 /S 开关
        - 正好两个引号字符
        - 在两个引号字符之间无任何特殊字符,
          特殊字符指下列字符: &<>()@^|
        - 在两个引号字符之间至少有
          一个空格字符
        - 在两个引号字符之间的字符串是某个
          可执行文件的名称。

    2.  否则,老办法是看第一个字符
        是否是引号字符,如果是,则去掉首字符并
        删除命令行上最后一个引号,保留
        最后一个引号之后的所有文本。

第 1 点中提到了 正好两个引号字符 ,也就是你给后面 wd 后面的参数不加双引号就正常了 的原因。

然后注意看第 2 点,也就是说实际执行的应该是

C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c

注意,前面没有引号,也就是导致报错的原因了,那我们应该怎么改呢?答案是在首尾再添加一个双引号。

即最终成

os.system(f'"{chrome} --args --new-window "https://baidu.com/s?wd={content}"')

即可调用成功。

但是这样并不优雅,要使用优雅的方案的话,更加推荐使用。

import subprocess

chrome = r'C:\Program Files\Google\Chrome\Application\chrome.exe'
content='a b c'.replace(' ', '%20')

cmd = [chrome, '--args', '--new-window' , f'https://baidu.com/s?wd={content}']
subprocess.call(cmd)

参考

从前我也有这样的问题,在网上搜到了答案,不过我现在找不到那篇文章了,大意就是 os.system() 传到 cmd 的命令如果首尾都有双引号,那么会把首尾这俩双引号看成一对,所以会出错。另外,还可以看一下 os.popen(),这个函数会返回命令行的输出而不是 os.system() 返回的状态码。如下图,使用 os.popen() 时就不需要再多加一对双引号了,加了反而还会出错。
image.png

C:\Users\username>"C:\Program Files\Google\Chrome\Application\chrome.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"
系统找不到指定的路径。

C:\Users\username>"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"

C:\Users\username>python
Python 3.10.5 (tags/v3.10.5:f377153, Jun  6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system('"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"')
'C:\Program' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
1
>>> os.system('""C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c""')
0
>>> os.popen('"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c"')
<os._wrap_close object at 0x000001D9CAD45EA0>
>>> os.popen('""C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --args --new-window https://baidu.com/s?wd="a%20b%20c""')
<os._wrap_close object at 0x000001D9CAD45F30>
>>> '""C:\Program' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏