期待 - 远程命令的直接输出到本地文件
问题描述:
我想打电话从庆典的期待脚本方式如下:期待 - 远程命令的直接输出到本地文件
#!/bin/bash
mkfifo foobar
expectScript > foobar &
# other stuff that does stuff with foobar
什么expectScript需要做的是ssh到远程主机。从那里它需要ssh到另一个远程主机。然后它需要将用户切换到根(不允许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 [email protected]$HOST1
# ssh keys are exchanged with HOST1, so there is no need for password here
expect -re "$HOST1_PROMPT" {
send "ssh [email protected]$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
答
您应该能够使用的控制字符发送到远程回声的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 "$ "
如果我运行此,重定向标准输入为空,在shell我可以按下Ctrl-C的背景和它结束干净。
./prog </dev/null >/tmp/out &
这个'expect'脚本的大部分内容可以简单地通过使用公钥认证和内建在'ssh'中的隧道支持来消除。 – chepner
谢谢chepner,但没有太多可以消除,因为在HOST2上我需要以root用户身份运行命令(sudo无法运行),并且HOST2不允许root通过ssh登录。所以有必要首先以非root用户身份登录,然后su登录到root用户。我已经在公钥认证工作的主机上实现了该解决方案,并且更容易。但对于这个特定的服务器,我不明白它是如何工作的。 –
如果你有root密码,你可以*配置*'sudo'工作。而且没有什么能够阻止你在你本地的'ssh'配置文件中设置正确的用户ID和主机名。 – chepner