我需要使用Python 脚本生成echo
并调用 JSON 配置文件。tee
通过反复试验,我发现我必须使用单引号。然而我并不理解使用 Python 时遇到的所有行为run()
。以下代码打印我的问题:
#!/usr/bin/env python3
from subprocess import run
conf_file="""{
"alt-speed-down": 50,
}"""
print("Question 1. It does not work with double quotes. Why?")
run(f"""echo "{conf_file}" """, shell=True)
print("It works with single quotes.")
run(f"""echo '{conf_file}'""", shell=True)
conf_file="""{
\"alt-speed-down\": 50,
}"""
print("""Question 2. It does not work with double quotes, even when I escape the quotes.
Whereas when I type in my shell:
echo "\"This is a quoted string.\""
it works. Why?
""")
run(f"""echo "{conf_file}" """, shell=True)
print("""Question 3. It works with single quotes, even with escaped quotes.
whearas when I type in my shell:
echo '\"this is quoted\"'
I get the backslashes printed. Why aren't
the backslashes printed when called with Python's run()?""")
run(f"""echo '{conf_file}'""", shell=True)
我使用 Bash 作为我的 shell。为什么从我的 Bash shell 中转义双引号与 Python 中的转义双引号不同?我是否没有通过shell=True
in指定来访问我的 Bash shell
run()
?
PS 我知道用json
模块生成 JSON 是一种方法,但就我而言,它主要是从备份的配置文件中复制现有的 JSON。我想避免将此类 JSON 文件读入脚本中的字符串 - 该脚本旨在在新重新安装的操作系统上运行,此类备份最初不可用。这就是为什么我需要在 Python 字符串中有许多字符串变量来存储此类 JSON 配置文件
答案1
关于引号,撇开换行符不谈,是这样的:
conf_file="""{ "alt-speed-down": 50, }"""
将字符串分配{ "alt-speed-down": 50, }
给变量。然后当你运行时run(f"""echo "{conf_file}" """, shell=True)
,shell 会看到该字符串
echo "{ "alt-speed-down": 50, }"
这与单引号不同:
echo '{ "alt-speed-down": 50, }'
conf_file="""{ \"alt-speed-down\": 50, }"""
在这里,反斜杠转义了双引号,并被 Python 删除,因此这相当于第一个。此处不需要转义引号,但如果您有的"{ \"alt-speed-down\": 50, }"
话,则需要转义引号。
如果你想在Python字符串中保持反斜杠完整,你需要使用r''
字符串,例如r'{ \"alt-speed-down\": 50, }'
(或与双引号相同,r"{ \"alt-speed-down\": 50, }"
实际上也有效,并且反斜杠不会被删除,即使它们被要求不结束带引号的字符串。)
在 shell 中,单引号内的反斜杠不会被处理,所以
echo '\"this is quoted\"'
传递给echo
字符串\"this is quoted\"
。尽管 的某些实现echo
会处理转义符,例如\n
,无论 shell 命令行处理中发生什么。
而与
run(f"""echo '{conf_file}'""", shell=True)
你看不到反斜杠。
简而言之,shell 和 Python 之间的引用规则是不同的。
看:
- https://docs.python.org/3/tutorial/introduction.html#strings
- shell 中的 "..."、'...'、$'...' 和 $"..." 引号之间有什么区别?
- 为什么 printf 比 echo 更好?
正如评论中提到的,从 Python 生成 JSON(或 YAML 或其他)可能比手动打印字符串更好。例如json
模块:
>>> import json
>>> obj = {}
>>> obj["alt-speed-down"] = 50
>>> json.dumps(obj)
'{"alt-speed-down": 50}'