在 shell 中嵌套引号

在 shell 中嵌套引号

我想执行一个看起来像的命令

$ sh -c 'exec python -c "print('$1$2MyString')"'

与期望的结果'$1$2MyString'

但是,当我执行命令时,我得到

Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'MysString' is not defined

据我所知,当我添加第三级引号时,它实际上将命令分成两部分,并且 shell 会看到$1$2MyString外部引号并尝试替换已知值。

如果我转义单引号,

$ sh -c 'exec python -c "print(\'$1$2MyString\')"'

我收到以下错误:

sh: 1: Syntax error: "(" unexpected

本质上,我的问题是:有没有办法在上面的 print 函数中引入字符串文字?

答案1

您无法在单引号字符串内转义单引号。例如,这是一个不完整的行:

echo 'boy\'s game'    # Wrong!
>

但是,您可以邻接由不同类型的引号括起来的字符串:

echo "boy's"' game'    # Right
boy's game

因此,您可以引用引号"'"等:

sh -c 'exec python -c "print('"'"'$1$2MyString'"'"')"'
#     ^-. . . . . . . . . . -^   ^-. . . . . -^   ^--^
#                             ^-^              ^-^

此输出是MyString因为 是$1$2通过调用 进行评估的sh。如果您想要$1$2MyString作为文字,您需要确保它位于单引号内并受到显式保护sh

sh -c 'exec python -c '"'"'print("$1$2MyString")'"'"
#     ^-. . . . . . .-^   ^-. . . . . . . . . .-^

答案2

引号从不嵌套(除了命令替换):在单引号字符串中,双引号是常规字符,不充当引号。反之亦然。

如果你想将参数传递给python print('$1$2MyString'),你可以进行必要的转义,但由于字符串同时包含单引号和美元符号,这会变得很尴尬,这意味着如果不进一步转义,单引号和双引号都不能使用。即使对于该字符串本身,更不用说考虑所需的第二级引用了。

或者,执行一些操作,例如将字符串通过环境传递到sh

code="print('\$1\$2MyString')"  # or
code='print('\''$1$2MyString'\'')'

code=$code sh -c 'exec python -c "$code"'

或者,如果输出应该是'$1$2MyString', 带单引号,那么 Python 代码需要是print("'$1$2MyString'")

code='print("'\''$1$2MyString'\''")'
code=$code sh -c 'exec python -c "$code"'

将 Python 代码放入文件中可能会更简单。

相关内容