首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从多个ssh awk输出将变量复制到本地文本文件

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

Stack Overflow用户
提问于 2021-02-12 21:27:46
回答 3查看 225关注 0票数 2

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

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

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

代码语言:javascript
复制
> testfile.txt

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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-02-13 00:16:04

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

  • 由于<<-语法而缩进选项卡。这纯粹是表面的,并使您的代码更readable.
  • avoiding,转义像$这样的特殊字符,引用EOF。这不仅是表面的,而且使您的代码不那么容易出错。

这意味着:

代码语言:javascript
复制
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}”。除非您知道自己在做什么,否则在使用变量时,一定要用双引号括起来,以避免任何不受欢迎的side-effect.
  • You将df的结果放入变量VAL,并将其内容写入textfile.txt
    • 作为通用约定,使用小写表示变量名(除非它们被导出到环境中-这里的情况并非如此);也就是说,这应该是val,而不是val不会将任何东西写入textfile.txt,因为您的重定向在双引号中,因此属于echo-ed的文本。正确的命令是echo "$val" > testfile.txt
    • Now,:所有这些,包括这个echo都是在远程服务器上执行的,因此这将在那里创建文件testfile.txt,而不是在您的机器上。这不是您想要的,所以让我们删除echo行。让我们也移除val=,因为不再需要val
    • exit命令是不必要的。一旦最后一个命令被读取和执行,ssh会话就会结束ssh

我们只剩下这个了;

代码语言:javascript
复制
ssh "$CURRENT_ENV" <<- 'EOF'
        df -h | awk '$6 == "/" {print $5; exit}'
EOF

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

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

代码语言:javascript
复制
ssh {$CURRENT_ENV} <<- 'EOF' > testfile.txt
        df -h | awk '$6 == "/" {print $5; exit}'
EOF

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

代码语言:javascript
复制
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命令:

代码语言:javascript
复制
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之后)

这就是了!

票数 3
EN

Stack Overflow用户

发布于 2021-02-12 22:09:18

我觉得你能做到:

代码语言:javascript
复制
# 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 '$6 == "/" {print $5; exit}'

请注意,如果您使用df指定了一个文件路径,那么您就可以获得该文件路径的信息。在您的例子中,您只对/感兴趣,因此可以指定它。

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

代码语言:javascript
复制
df --output=pcent / | tail -n 1

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

代码语言:javascript
复制
df --output=pcent / | tail -n 1 | tr -d ' '

如果出于某种原因,您希望避免使用两个管道,但仍然希望删除前导空格,则可以使用awk

代码语言:javascript
复制
df --output=pcent / | awk 'NR == 2 {print $1}'

然而,使用awk可能会慢一些,我不确定。

票数 2
EN

Stack Overflow用户

发布于 2021-02-13 01:05:26

如果要将任何内容打印到本地文件,只需在EOF之后立即重定向,这里是如何将VAL写入远程文件和本地文件的示例。此外,您还可以使用df -输出页面只显示百分比列。不幸的是,没有隐藏头的选项,所以尾-n1

代码语言:javascript
复制
ssh {$CURRENT_ENV} << EOF >>localfile.txt
VAL=\$(df --output=pcent /|tail -n1)
echo "$VAL" > remotefile.txt
echo "$VAL" # for localfile
exit
EOF
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66179259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档