期望 - 将远程命令直接输出到本地文件

时间:2017-08-02 22:32:40

标签: linux bash stdout expect fifo

我试图通过以下方式从bash调用expect脚本:

#!/bin/bash

mkfifo foobar
expectScript > foobar &
# other stuff that does stuff with foobar

expectScript需要做的是ssh到远程主机。从那里它需要ssh到另一个远程主机。然后需要将用户切换到root(不允许root登录)。然后它需要发出一个最终需要写入foobar的命令(例如tail -f / var / log / messages)。没有其他东西可写入foobar,例如密码提示或命令提示。只能将命令的输出写入foobar。我有脚本的登录部分工作正常。我正在努力的是如何使输出被写入foobar,以这种方式SIGINT将杀死命令。

这就是我所拥有的:

#!/usr/bin/expect --

set HOST1_USER myuser
set HOST2_USER myotheruser
set HOST1_PASSWORD mypassword
set HOST2_PASSWORD myotherpassword
set ROOT_PASSWORD anotherpassword
set HOST1 192.168.0.5
# HOST2 is only reachable from HOST1
set HOST2 192.168.1.12

global until_interrupt
set until_interrupt 0

set HOST1_PROMPT "CL-\\d.*#"
set HOST2_PROMPT "\\\$ $"
set ROOT_PROMPT "# $"

log_user 0

spawn ssh $HOST1_USER@$HOST1
#   ssh keys are exchanged with HOST1, so there is no need for password here
    expect -re "$HOST1_PROMPT" {
            send "ssh HOST2_USER@$HOST2\n"
            expect {
                    -re ".*ssword.*" { send "$HOST2_PASSWORD\n" }
                    -re ".*Are you sure you want to continue connecting.*" {send "yes\n"; exp_continue}
            }
    }

    expect -re "$HOST2_PROMPT" { send "su\n" }
    expect -re ".*ssword.*" { send "ROOT_PASSWORD\n" }

    log_user 1
    # nothing up to this point should have been sent to stdout
    # now I want the output of the tail command to be sent to stdout

    expect -re "$ROOT_PROMPT" { send "tail -f /var/log/messages\n" }

    # I want to wait here until SIGINT is sent.  There may be a better way than the traps below.
    # Set a trap to watch for SIGINT
    trap {
            set until_interrupt sigint_detected
    } SIGINT

    while { $until_interrupt == 0 } {
            #wait until sigint
    }

    send "\003"
    # I think that is SIGINT, and that I'm sending it because I caught the first one in the trap.

    trap {
            exit
    } SIGINT

    set timeout 30

    expect -re "$ROOT_PROMPT" { send "exit\n" }
    expect -re "$HOST2_PROMPT" { send "exit\n" }
    expect -re "$HOST1_PROMPT" { send "exit\n" }
    # Fully exited

1 个答案:

答案 0 :(得分:0)

您应该能够使用expect来发送到远程控制字符的回显(或者不是由tail -f命令生成的其他字符串)。例如,这个简单的ssh示例适用于我(-d用于调试):

#!/usr/bin/expect -d
log_user 0
spawn ssh localhost
expect " $ "
send "tail -f /var/log/messages\n"
log_user 1
trap {  send "\003" } SIGINT
set timeout -1
expect "\003"
expect "$ "
send "date\r"
expect "$ "

如果我运行它,将stdin重定向为null,在shell的后台我可以输入Ctrl-C并且它会干净地结束。

./prog </dev/null >/tmp/out &