如何通过 SSH 传递复杂的 shell 命令以进行远程执行?我的命令会抛出语法错误或在本地进行解释!

如何通过 SSH 传递复杂的 shell 命令以进行远程执行?我的命令会抛出语法错误或在本地进行解释!

我有这样一个命令,它可以告诉我系统是否有磁盘已满(>=70%已满):

if [[ -n df -PTh|column -t|awk '{print $6 $7}'|awk -F"%" '{printf "%-9s %-5s\n",$1,$2}'|grep -v -e "Use" -e "Mounted"|awk '$1>70{printf "%-9s %-5s\n",$1,$2}' ]]; then echo "not present"; else echo ">70 is present"; fi

我想使用 SSH 在远程服务器上执行上述命令。例如:

ssh remoteserver "if [[ -n df -PTh|column -t|awk '{print $6 $7}'|awk -F"%" '{printf "%-9s %-5s\n",$1,$2}'|grep -v -e "Use" -e "Mounted"|awk '$1>70{printf "%-9s %-5s\n",$1,$2}' ]]; then echo "not present"; else echo ">70 is present"; fi"

但是当我尝试这样做时,出现了以下错误:

HOST: remoteserver bash: -c: line 0: syntax error in conditional expression bash: -c: line 0: syntax error near /home'
bash: -c: line 0:if [[ -n 92 /home'

答案1

首先,我将 awk/grep/awk/grep/awk/grep/etc 语句的战争罪行简化为:

df | awk '$5~/([7-9]|10)[0-9]/'

它能完成检查输出所需的所有工作。您可以{print ...}在语句中添加一个子句,awk如果您真的需要漂亮的输出,但考虑到你只是检查一下如果有输出,我们合理点处理这件事☺。

我们还可以缩短 if/else。我还更正了方向——你的方向是相反的。整个命令现在看起来像:

[[ -n $(df | awk '$5~/([7-9]|10)[0-9]/') ]] && echo 'ACHTUNG!' || echo 'No >=70s'

我想你会同意这只是轻微地更有启发。

现在你可能可以手动将其转义并将其包装起来,bash -c "..."但这样做有什么乐趣呢?相反,让我们将命令保存到本地文件(例如commands.txt)中,你可以像这样将其发送到服务器:

ssh user@host $(<commands.txt)

你可以把它留在那里。你实际上可以将原始命令的工作版本放入其中并将其发送过去。这个东西非常强大……但我们不想这样做……当我们可以更聪明(和欺骗性地)使用命令并取消 if 括号(这是导致转义问题的原因)时,我们不想这样做。

我们目前正在df远程运行并远程处理它。我们不需要这样做。我们可以让它ssh运行df,然后在本地处理输出。这立即解决了转义问题,但我们目前被逻辑[[括号束缚着]],这会让重写有点难看:

[[ -n $(ssh user@host df | awk '$5~/([7-9]|10)[0-9]/') ]] && .......

真恶心。
我们比那更好。
与在我们之前走过的猴子和猿猴不同,我们有退出代码。

当某些程序运行完毕时,它会返回一个代码。这些代码表示各种各样的东西但一般来说,0意思是“我完全按照我的设计去做了”,而任何更高级别的表达都意味着“我做得不好,Bawss”。

条件钩子&&||根据输入的退出代码来决定是否运行。在我们的例子中,这意味着如果我们awk以非零方式退出,我们就可以控制代码流:

ssh user@host df | awk '$5~/([7-9]|10)[0-9]/ {exit 1}' && echo 'No >=70s' || echo 'ACHTUNG!'

这也意味着它会在检测到第一个 >=70 的值时立即退出。如果你有数百万个驱动器,这可以为你节省优于其他领先品牌的脚本。所以是的,只是为了重申这个最终版本中发生的事情:

  1. 我们正在连接服务器并df远程运行
  2. 输出通过管道传输回本地实例awk
  3. awk查看第五列是否与正则表达式匹配以匹配 70-100
  4. 如果是,则退出代码 1,并||执行代码(那里驱动器使用率超过 70%)
  5. 如果没有,它将退出代码 0 并&&执行代码。

在之前的修订中,我也NR>1awk语句进行了检查,但考虑到我们明确检查了第五列的值(并且它必须是一个数字才能工作),我们也可以放心地省略它。

相关内容