【问题标题】:Escaping special characters with sh -c使用 sh -c 转义特殊字符
【发布时间】:2016-10-10 17:54:25
【问题描述】:

当我从 shell 运行以下命令时,它工作正常:

# ./testdollar.py 1 2 '"source"="Zabbix"|| "name"="testlog trigger"|| "trigger_name"="*UNKNOWN*"|| "trigger_group"="Zabbix servers"|| "trigger_description"=""|| "id"="291058"|| "item_name"="Testlog"|| "item_value"="HFD3D$01"|| "item_lastvalue"="HFD3D$01"|| "reference_url"="http://test"|| "status_open"="1"|| "hostname"="Zabbix server"||
"ip"="10.10.10.1"|| "value"="1"|| "event_id"="62510700"|| "severity"="Not classified"||
"datetime_item_cst"="1969.12.31 18:00:00"|| "datetime_cst"="2016.10.07 03:59:08"|| "sourceid"="62510700"'

但我需要将其运行为:

sh -c "带参数的整个命令"

我试过了:

sh -c /data/zabbix/share/zabbix/alertscripts/testdollar.py 1 2 '"source"="Zabbix"|| "name"="testlog trigger"|| "trigger_name"="*UNKNOWN*"|| "trigger_group"="Zabbix servers"|| "trigger_description"=""|| "id"="291058"|| "item_name"="Testlog"|| "item_value"="HFD3D$01"|| "item_lastvalue"="HFD3D$01"|| "reference_url"="http://test"|| "status_open"="1"|| "hostname"="Zabbix server"||
"ip"="10.10.10.1"|| "value"="1"|| "event_id"="62510700"|| "severity"="Not classified"||
"datetime_item_cst"="1969.12.31 18:00:00"|| "datetime_cst"="2016.10.07 03:59:08"|| "sourceid"="62510700"'

给出以下错误,这表明它无法读取包含大量引号的第三个参数:

Traceback (most recent call last):
  File "/data/zabbix/share/zabbix/alertscripts/testdollar.py", line 3, in <module>
    data=sys.argv[3]
IndexError: list index out of range

试过这个:

sh -c '/data/zabbix/share/zabbix/alertscripts/testdollar.py 1 2 "source"="Zabbix"|| "name"="testlog trigger"|| "trigger_name"="*UNKNOWN*"|| "trigger_group"="Zabbix servers"|| "trigger_description"=""|| "id"="291058"|| "item_name"="Testlog"|| "item_value"="HFD3D$01"|| "item_lastvalue"="HFD3D$01"|| "reference_url"="http://test"|| "status_open"="1"|| "hostname"="Zabbix server"||
"ip"="10.10.10.1"|| "value"="1"|| "event_id"="62510700"|| "severity"="Not classified"||
"datetime_item_cst"="1969.12.31 18:00:00"|| "datetime_cst"="2016.10.07 03:59:08"|| "sourceid"="62510700"'

运行正常,但是当我检查命令的结果时,我可以看到它在 "source"="Zabbix"|| 之后停止读取第三个参数部分。如果我用双引号而不是单引号将整个内容括起来,也会发生同样的事情。

尝试了单引号和双引号的其他组合,但无法弄清楚。我需要在命令参数中转义特殊字符吗?如果有,怎么做?

编辑:

更简单的测试方法:

sh -c 'echo '"A=x"||"B=y"||"C=z"''
A=x

【问题讨论】:

  • 尝试将多行参数括在三引号之间,'''like this'''
  • 试过:sh -c 'command 1 2 '''long argument'''' 和 sh -c "command 1 2 '''long argument'''" 发生同样的事情。
  • sh -c $'testdollar.py 1 2 \'"A"||"B"||"C"\''
  • 这行得通,但有什么办法可以让它在开头没有美元符号的情况下工作?
  • 没有美元符号是它起作用的原因......

标签: bash


【解决方案1】:

您应该在整个命令周围使用双引号,然后在命令字符串中转义双引号:

sh -c "echo '\"A=x\"||\"B=y\"||\"C=z\"'"

请记住,参数将在双引号内展开,因此如果您的字符串中有任何$,那么您需要将它们转义为\$

替代方案不是特别吸引人:

sh -c 'echo '"'"'"A=x"||"B=y"||"C=z"'"'"''

要在单引号字符串中使用单引号 ''"'"' 会关闭原始字符串,插入双引号单引号,然后重新打开单引号字符串。

如果您专门针对 Bash,那么您还可以使用“C 样式”/ANSI 字符串:

sh -c $'echo \'"A=x"||"B=y"||"C=z"\''

$' ' 内,可以使用\' 插入单引号。

【讨论】:

  • 什么 bash 不支持 ansi 字符串?
  • @123 我没有意识到它已经支持了这么久 - 我已经编辑了我的答案,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 2016-05-01
  • 2019-01-29
相关资源
最近更新 更多