【问题标题】:Extract EXPECT result to local variable/file将 EXPECT 结果提取到局部变量/文件
【发布时间】:2022-12-06 00:07:04
【问题描述】:

我一直在努力将远程服务器的输出输出到本地变量或本地文件。

我的尝试:

#!/bin/bash

my_pass=!!psw!!
server=10.10.10.10
/usr/bin/expect << ENDOFEXPECT
    exp_internal 1      ;# expect internal debugging. remove when not needed
    set PROMPT  ":~ ?# ?"
    set timeout 30

    spawn bash -c "ssh root@$server"  
    expect "assword:"
    send "$my_pass\r"
    expect -re "$PROMPT"

    send -- "df -kh /\r" 
    expect -re "df\[^\n]+\n.+\n(.+\r\n.+)\r\n"
    set command_output $expect_out(1,string)
    send_user "$command_output\r"

    interact
ENDOFEXPECT

echo "====================="
echo " >> $command_output"

输出:

spawn bash -c ssh root@10.10.10.10
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {154725}

expect: does "" (spawn_id exp4) match glob pattern "assword:"? no
Password: 
expect: does "\rPassword: " (spawn_id exp4) match glob pattern "assword:"? yes
expect: set expect_out(0,string) "assword:"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "\rPassword:"
send: sending "!!psw!!\r" to { exp4 }
Gate keeper glob pattern for '' is ''. Not usable, disabling the performance booster.

expect: does " " (spawn_id exp4) match regular expression ""? (No Gate, RE only) gate=yes re=yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) ""
send: sending "df -kh /\r" to { exp4 }
Gate keeper glob pattern for 'df[^
]+
.+
(.+
.+)
' is ''. Not usable, disabling the performance booster.

expect: does " " (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no


expect: does " \r\n" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
Last login: Fri Dec  2 23:58:09 2022 from 10.10.10.1

Welcome to server image 2.2


expect: does " \r\nLast login: Fri Dec  2 23:58:09 2022 from 10.10.10.1\r\r\n\r\nWelcome to server image 2.2\r\n\r\n" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
REMY_SERVER:~ # 
expect: does " \r\nLast login: Fri Dec  2 23:58:09 2022 from 10.10.10.1\r\r\n\r\nWelcome to server image 2.2\r\n\r\n\u001b[?1034h\u001b[1m\u001b[31mREMY_SERVER:~ # \u001b(B\u001b[m" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
expect: timed out
interact: received eof from spawn_id exp0
=====================
 >> 

预期的:

我最终想要的是将 df -kh 的输出放入局部变量或更好,将其直接附加到本地文件(在本地机器上,而不是执行命令的服务器上),以便它包含类似:

$ cat ./result.txt
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        20G   18G  1,7G  92% /

【问题讨论】:

  • 您不能设置 ssh 密钥吗?那会使事情变得容易得多。
  • 你可以spawn bash -c "ssh root@$server df -kh &gt;&gt; /the/local/file"

标签: bash ssh expect


【解决方案1】:

方法 1:正确的方法是不使用 expect 并使用密钥对访问:

步骤1

设置 SSH 密钥对(google it),然后将 SSH 密钥复制到远程服务器。为此,我建议使用 ssh-copy-id。

第2步

现在有了使用密钥通过 SSH 连接到服务器的能力,您的上述问题就变成了:

$ ssh root@10.10.10.10 "df -kh"

您可以想象并使用此处文档(heredocs 又名 here-docs)来进一步增强此技术。

$ ssh root@10.10.10.10 <<EOF
> df -kh
> EOF

或者将命令放在文件中并将它们传递给 ssh:

$ ssh root@10.10.10.10 < my.cmds

方法二:期待

请参阅以下内容,解释如何正确使用它以及创建期望脚本的工具 https://hostadvice.com/how-to/how-to-automate-tasks-in-ssh/

【讨论】:

    【解决方案2】:

    首先,您的 PROMPT 正则表达式不匹配。我看到输出中有一些颜色代码:

    expect: does " 
    Last login: ...REMY_SERVER:~ # u001b(Bu001b[m" (spawn_id exp4) match regular expression  ...
    

    锚定提示正则表达式并将它们括在大括号中是很好的。尝试

        set PROMPT { # S*$}
    

    或者,假设登录 shell 是 bash,设置一个更容易匹配的新提示:

        send "$my_pass
    "
        expect "Welcome to server"
        send -- "PS1='>'
    "
        set PROMPT {>$}
        expect -re $PROMPT
    

    接下来是题目的相关代码。

        send -- "df -kh /
    " 
        expect -re "df[^
    ]+
    .+
    (.+
    .+)
    "
        set command_output $expect_out(1,string)
        send_user "$command_output
    "
    

    我会调整你的正则表达式:

        set cmd "df -kh /" 
        send -- "$cmd
    "
        expect -re "$cmd
    (.+)
    .*$PROMPT"
    

    然后您将正确捕获并“回显”结果

        set command_output $expect_out(1,string)
        send_user "$command_output
    "
        # use a newline here ......^
    

    并将其附加到本地文件:

        set fh [open ./results.txt a]
        puts $fh $command_output
        close $fh
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 2022-01-05
      • 2013-04-30
      相关资源
      最近更新 更多