首页 > 解决方案 > 将变量从多个 ssh awk 输出复制到本地文本文件

问题描述

我对 shell 脚本相当陌生,所以我很难将类似问题的答案应用于我的问题。

我正在尝试 ssh 到远程服务器,执行多个 awk 命令,并将每个命令的值返回到本地 .txt 文件。我也在尝试 ssh 到其他服务器,执行类似的命令,并将它们返回到同一个文本文件。

如果我手动 ssh 到远程服务器并运行,df -h | awk '$6 == "/" {print $5; exit}我会从 df -h 命令获取根目录的 % used 值。到目前为止,我有以下内容,但是当它进入和退出远程服务器时,它不会保存值。

> testfile.txt

ssh {$CURRENT_ENV} << EOF
VAL=\$(df -h | awk '\$6 == "/" {print \$5; exit}')
echo "\$VAL > testfile.txt"
exit
EOF

我查看了单行 awk 返回,但由于我有多个命令要运行,它似乎不是最优的。我将不胜感激任何建议!

标签: bashshellawksshscripting

解决方案


首先,你的ssh命令。使用 here-document 是个好主意。您可以通过以下两种方式对其进行改进:

  • 由于<<-语法的原因,使用 TAB 缩进。这纯粹是装饰性的,使您的代码更具可读性。
  • 避免特殊字符的转义,例如$quoting EOF。这不仅是装饰性的,而且使您的代码不易出错。

这给出了:

ssh {$CURRENT_ENV} <<- 'EOF'
        VAL=$(df -h | awk '$6 == "/" {print $5; exit}')
        echo "$VAL > testfile.txt"
        exit
EOF

(我们甚至可以在 EOF 之前放一个表格)

现在你的代码:

  • 你没有告诉我们 CURRENT_ENV 是什么。我认为这类似于user@server. 要使用该变量,请写入"$CURRENT_ENV",而不是 '{CURRENT_ENV}'。除非您知道自己在做什么,否则在使用变量时,请始终将其括在双引号中以避免任何不良副作用。
  • 您将结果df放入变量VAL并将其内容写入textfile.txt
    • 作为通用约定,对变量名使用小写(除非它们被导出到环境中,而这里不是这种情况);即这应该是val,不是VAL
    • echo "$val > testfile.txt"不会向 textfile.txt 写入任何内容,因为您的重定向在双引号内,因此属于echo-ed 的文本。正确的命令是echo "$val" > testfile.txt
    • 现在,考虑一下:所有这些,包括这个echo都在远程服务器上执行,因此这将在testfile.txt那里创建文件,而不是在你的机器上。这不是您想要的,所以让我们删除该echo行。让我们也删除val=,因为val不再需要。
    • exit命令是不需要的。一旦最后一个命令将被读取并执行,ssh会话无论如何都会结束。

我们只剩下这个了;

ssh "$CURRENT_ENV" <<- 'EOF'
        df -h | awk '$6 == "/" {print $5; exit}'
EOF

(请记住这是之前的列表,df但在这种情况下单个空格不会有害)

就像现在一样,您的代码将所有内容输出到您的终端。现在让我们将其重定向到您的本地文件testfile.txt

ssh {$CURRENT_ENV} <<- 'EOF' > testfile.txt
        df -h | awk '$6 == "/" {print $5; exit}'
EOF

好的,这适用于一台服务器。你告诉我们实际上有几个。你没有向我们展示你的代码,所以我假设某处有一个循环:

for ssh_target in u1@server1 u2@server2 ...; do
    ssh "$ssh_target" <<- 'EOF' > testfile.txt
        df -h | awk '$6 == "/" {print $5; exit}'
EOF
done

差不多好了!这个命令的问题是每个循环都会覆盖testfile.txt. 解决方案是重定向for循环,而不是其中的ssh命令:

for ssh_target in u1@server1 u2@server2 ...; do
    ssh "$ssh_target" <<- 'EOF'
        df -h | awk '$6 == "/" {print $5; exit}'
EOF
done > testfile.txt

(重定向必须放在后面done

这里是!


推荐阅读