将变量从多个 ssh awk 输出复制到本地文本文件

Copying variables to local text file from multiple ssh awk output

我是 shell 脚本编写的新手,所以我很难将类似问题的答案应用到我的问题中。

我正在尝试通过 ssh 连接到远程服务器,执行多个 awk 命令,并将每个命令的值 return 保存到本地 .txt 文件。我也在尝试通过 ssh 连接到其他服务器,执行类似的命令,然后 return 将它们发送到同一个文本文件。

如果我手动 ssh 进入远程服务器并且 运行 df -h | awk ' == "/" {print ; 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 returns,但由于我有多个命令 运行 它似乎不是最佳选择。如果有任何建议,我将不胜感激!

我认为你可以做到:

# Write all of this script's stdout to testfile.txt
> testfile.txt

# Run df -h on remote host, and pipe the stdout of df -h to awk
ssh "$host" df -h | awk ' == "/" {print ; exit}'

请注意,如果您使用 df 指定一个文件路径,那么您只能获取该文件路径的信息。在您的情况下,您只对 / 感兴趣,因此您可以指定它。

如果您只对使用的百分比感兴趣,可以使用 --ouput=pcent 选项,然后使用 tail 只获取百分比部分(省略 Use% header):

df --output=pcent / | tail -n 1

如果使用的百分比小于 100%,这将生成带有一个或两个前导空格的输出。可以使用 tr:

删除前导空格
df --output=pcent / | tail -n 1 | tr -d ' '

如果出于某种原因你想避免有两个管道,但你仍然想删除前导空格,你可以使用 awk:

df --output=pcent / | awk 'NR == 2 {print }'

但是使用 awk 可能会更慢,我不确定。

首先,您的 ssh 命令。使用此处文档是个好主意。您可以通过以下两种方式改进它:

  • 由于 <<- 语法,使用制表符缩进。这纯粹是装饰性的,可以使您的代码更具可读性。
  • 通过引用 EOF 来避免转义 $ 等特殊字符。这不仅美观,而且使您的代码更不容易出错。

这给出:

ssh {$CURRENT_ENV} <<- 'EOF'
        VAL=$(df -h | awk ' == "/" {print ; 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 编辑的文本。正确的命令是 echo "$val" > testfile.txt
    • 现在,考虑一下:所有这一切,包括这个 echo 都是在远程服务器上执行的,因此这将在远程服务器上创建文件 testfile.txt,而不是在您的机器上。这不是您想要的,所以让我们删除 echo 行。我们也删除 val=,因为不再需要 val
    • 不需要exit命令。一旦读取并执行最后一个命令,ssh 会话无论如何都会结束。

我们只剩下这个了;

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

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

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

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

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

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

快到了!这个命令的问题是每次循环都会覆盖testfile.txt的内容。解决方案是重定向 for 循环,而不是其中的 ssh 命令:

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

(重定向必须放在done之后)

在这里!

如果你想打印任何东西到本地文件,在 EOF 后立即重定向 这里是如何将 VAL 写入远程文件和本地文件的示例。您也可以使用 df --output pcent 仅显示百分比列。不幸的是没有隐藏 header 的选项,所以 tail -n1

ssh {$CURRENT_ENV} << EOF >>localfile.txt
VAL=$(df --output=pcent /|tail -n1)
echo "$VAL" > remotefile.txt
echo "$VAL" # for localfile
exit
EOF