5

我正在尝试在 bash 脚本中使用 curl 通过 pushover 发送通知。我无法curl -F正确解释换行符。

curl -s \
-F "token=TOKEN" \
-F "user=USER" \
-F "message=Root Shell Access on HOST \n `date` \n `who` " \
https://api.pushover.net/1/messages.json > NUL

我试过了:

\n 
\\\n 
%A0

我宁愿直接推送消息,而不是通过文件。

4

1 回答 1

6

curl不解释反斜杠转义,因此您必须在curl看到的参数中插入一个实际的换行符。换句话说,您必须让 shell(bash在这种情况下)来解释\n,或者您需要插入一个真正的换行符。

Posix 标准 shell 不会像 一样解释 C 转义\n,尽管标准实用程序命令printf可以。但是,bash确实提供了一种方法:在引号形式中,$'...'C 样式的反斜杠转义将被解释器。否则,$'...'就像 一样'...',因此不会发生参数和命令替换。

但是,任何 shell(包括bash)都允许换行符出现在引号内,并且换行符只是按原样传递。所以你可以写:

curl -s \
     -F "token=$TOKEN" \
     -F "user=$USER" \
     -F "message=Root Shell Access on $HOST
$(date)
$(who)
" \
     https://api.pushover.net/1/messages.json > /dev/null

(注意:我在原始命令中似乎缺少参数扩展的地方插入了参数扩展,并将curl已弃用的反引号命令替换更改为推荐的$(...)形式。)

如上所述,包含文字换行符的唯一问题是,如果您关心外观,它会弄乱缩进。所以你可能更喜欢 bash 的$'...'形式:

curl -s \
     -F "token=$TOKEN" \
     -F "user=$USER" \
     -F "message=Root Shell Access on $HOST"$'\n'"$(date)"$'\n'"$(who)" \
     https://api.pushover.net/1/messages.json > /dev/null

这也有点难以阅读,但它是完全合法的。shell 允许单个参数(“单词”)由任意数量的带引号或不带引号的段组成,只要段之间没有空格。但是你可以通过预定义一个变量来避免多引号语法,有些人觉得它更具可读性:

NL=$'\n'
curl -s \
     -F "token=$TOKEN" \
     -F "user=$USER" \
     -F "message=Root Shell Access on $HOST$NL$(date)$NL$(who)" \
     https://api.pushover.net/1/messages.json > /dev/null

最后,printf如果您更习惯这种风格,您可以使用标准实用程序:

curl -s \
     -F "token=$TOKEN" \
     -F "user=$USER" \
     -F "$(printf "message=Root Shell Access on %s\n%s\n%s\n" \
                  "$HOST" "$(date)" "$(who)")" \
     https://api.pushover.net/1/messages.json > /dev/null
于 2014-05-29T15:14:49.350 回答