![如何在 bash 中执行带有多个嵌套单引号和双引号以及带引号的变量的命令](https://linux22.com/image/156436/%E5%A6%82%E4%BD%95%E5%9C%A8%20bash%20%E4%B8%AD%E6%89%A7%E8%A1%8C%E5%B8%A6%E6%9C%89%E5%A4%9A%E4%B8%AA%E5%B5%8C%E5%A5%97%E5%8D%95%E5%BC%95%E5%8F%B7%E5%92%8C%E5%8F%8C%E5%BC%95%E5%8F%B7%E4%BB%A5%E5%8F%8A%E5%B8%A6%E5%BC%95%E5%8F%B7%E7%9A%84%E5%8F%98%E9%87%8F%E7%9A%84%E5%91%BD%E4%BB%A4.png)
这是我的简单脚本
#!/bin/sh
thefile=/home/ark/arkserver/ShooterGame/Saved/SaveIsland/1288804998.arktribe
while inotifywait "${thefile}" ; do
a=\"`strings ${thefile} | tail -n 5 | head -n 1 | sed 's/<[^>]*>//g'`\"
echo $a
curl -H "Content-Type: application/json" -X POST -d '{\"username\": \"Island\", \"content\": $a}' https://discordapp.com/api/webhooks/5738674701/OjRQiAWHq5mX0Tn2MfBlF-mI41TWrVYVAbOfXpeZWqo8
done
这是输出
Setting up watches.
Watches established.
/home/ark/arkserver/ShooterGame/Saved/SaveIsland/1288804998.arktribe ATTRIB
"Day 600, 21:31:17: Phorce1 demolished a 'Campfire'!"
{"code": 50006, "message": "Cannot send an empty message"}Setting up watches.
Watches established.
我不知道如何正确引用curl 命令并在中间插入变量。该命令应该是这样的。在命令行中输入时这有效
curl -H "Content-Type: application/json" -X POST -d '{"username": "test", "content": "Day 600, 14:51:00: Phorce1 demolished a 'Campfire'!"}' https://discordapp.com/api/webhooks/594723628738674701/OjRQn2MfBlF-FJVl1cWwMlD6UQf0c
我尝试过许多不同形式的引用。事实上,它与正确引用的 $a 相呼应,但仍然破坏了使用它的命令中的某些内容,这让我感到困惑。
(是的,我破坏了我的网络钩子地址)
这个问题被标记为重复另一个问题,但这个问题的答案只是简单地转义引号。我的脚本中的curl 命令行的“嵌套引号”性质导致这些答案失败。在发布我自己的问题之前,我尝试了多种形式的转义引用。使用另一个问题的答案中提到的转义引号,我可以毫无问题地得到引号内变量的简单“回显”,但将“在另一组引号内的其他引号内的引号内”插入到卷曲命令行将失败。
答案1
单引号防止变量扩展。
我会这样做:
url=https://discordapp.com/api/webhooks/5738674701/OjRQiAWHq5mX0Tn2MfBlF-mI41TWrVYVAbOfXpeZWqo8
while inotifywait "$thefile" ; do
a=$(strings "$thefile" | tail -n 5 | head -n 1 | sed 's/<[^>]*>//g')
echo "$a"
payload=$(printf '{"username": "Island", "content": "%s"}' "$a")
curl -H "Content-Type: application/json" -X POST -d "$payload" "$url"
done
您不需要转义单引号内的双引号。事实上,如果这样做,转义字符将被保留为文字字符。
始终引用您的变量,除非您确切知道如果不引用会发生什么。
(这是个人风格的问题)你不需要将变量括在引号内,除非您需要消除变量名称与周围文本的歧义:
echo "$aVariable"
echo "${aVariable}_abc"
答案2
要创建包含用户提供的数据的 JSON 文档并对其进行正确编码等,请使用类似以下内容的内容jq
:
payload=$( jq --arg content "$data" -n '{"username": "Island", "content": $content}' )
这将创建一个小型 JSON 文档,其中包含键值字段中$payload
的值。该值将被正确引用(双引号和非 ASCII 字符等内容将被正确处理)。$data
content
例如,如果$data
是,字面意思是
"hello
world"
(包括引号和换行符),上面的命令将创建以下 JSON 文档并将其分配给 thopayload
变量:
{
"username": "Island",
"content": "\"hello\nworld\""
}
要删除生成文档中无用的空格,请使用jq
其-c
选项。
完整的脚本看起来像
#!/bin/sh
url='https://discordapp.com/api/webhooks/5738674701/OjRQiAWHq5mX0Tn2MfBlF-mI41TWrVYVAbOfXpeZWqo8'
file='/home/ark/arkserver/ShooterGame/Saved/SaveIsland/1288804998.arktribe'
while inotifywait "$file" ; do
data=$( strings "$file" | tail -n 5 | head -n 1 | sed 's/<[^>]*>//g' )
payload=$( jq --arg content "$data" -n '{"username": "Island", "content": $content}' )
curl -H "Content-Type: application/json" \
-X POST \
-d "$payload" \
"$url"
done
您唯一需要担心的是 shell 变量的引用,它应该是双引号的照常。无需尝试将文字引号插入从管道读取的数据中。