在 Bash Shell 内以编程方式执行剪贴板内容(或更好的方法)

Programmatically Executing Clipboard Contents within Bash Shell (or Better Approach)

我目前正在开发一个 bash 脚本,它将使用一个webhook 如下所示:

##!/bin/bash

command=(curl -X POST -H \'Content-type: application/json\' --data \'{\"text\":\")
command+=("$(date)")
command+=(" IP: ")
command+=("$(hostname -I)")
command+=(\"}\' https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX)
"${command[@]}"

这意味着复制以下工作命令,同时允许可变时间戳和 IP:curl -X POST -H 'Content-type: application/json' --data '{"text":"Tue Jul 14 15:26:50 EDT 2020 IP: XX.X.X.XX"}' https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

这return一连串的错误(为此post手动将 IP 主机名更改为 X):

curl: (6) Could not resolve host: application
curl: (3) Port number ended with ':'
curl: (3) Port number ended with ' '
curl: (3) Host name 'X.X.X.XX ' contains bad letter
curl: (3) [globbing] unmatched close brace/bracket in column 2

我能够确定将 "${command[@]}" 替换为 echo "${command[@]}" | xclip -selection clipboard" 然后 手动 将其粘贴到终端中(右键单击 -> 粘贴)效果很好.不幸的是,我第一次想到使用 xclip -selection clipboard -o 似乎只是 return 字符串,就像 echo "${command[@]}" 一样。

有没有办法以编程方式将剪贴板内容作为命令粘贴到 shell 中并执行它们,或者甚至有办法调整初始 "${command[@]}" 调用以执行字符串?如果存在我没看到的明显更好的方法随时告诉我。

如果这对看到它的人来说是微不足道的,我提前道歉,但我对 Linux 系统和 bash 脚本编写都非常陌生。任何帮助将不胜感激。

问题是您创建了一个包含以下元素(每行一个)的数组:

curl
-X
POST
-H
'Content-type:
application/json'
--data
'{"text":"
<output of date>
 IP:
<output of hostname -I>
"}'
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

因此,将此数组作为命令执行有 'Content-type:application/json''{"text":"<output of date> IP:separate 命令参数。换句话说,当 "${command[@]}" 展开时,command 数组元素中的引号对 bash 没有意义。当您将扩展的结果复制并粘贴到您的终端时,bash 不再将其视为数组扩展的结果。相反,它将输入视为要解析为顶级命令的字符串,其中引号是有意义的。

要修复它,您只需要确保 command 数组的每个元素对应于您打算执行的命令的参数:

command=(curl -X POST -H 'Content-type: application/json')
command+=(--data '{"text":"'"$(date)"' IP: '"$(hostname -I)"'"}')
command+=(https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX)
"${command[@]}"

最终,除非您需要 command 数组用于脚本中的其他内容,否则您可以完全避免数组及其替换:

curl \
    -X POST \
    -H 'Content-type: application/json' \
    --data '{"text":"'"$(date)"' IP: '"$(hostname -I)"'"}' \
    https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

--data 的转义确实令人困惑;为了避免转义双引号,我混合了单引号和双引号字符串(在 bash 中将它们并排放置在一起,即 "foo"'bar' 变为 foobar)。