我需要自动化一个与远程设备兼容的过程,
这是步骤
已知的IP是telnet_ip,我想检索可以ssh进入的IP地址。
我想将这四个步骤自动化为一个名为get_ip
的函数,该函数会回显IP地址。我想按以下方式使用此功能
SSH_IP=$(get_ip 127.0.0.1 1000)
我环顾四周,发现可以使用expect
。我已经写了这个功能
function get_ip(){
expect << EOF
spawn telnet $1 $2
expect -ex "Escape character is '^]'."
send "\r"
expect {
-re ".*login: " {
send "root\r"
}
}
expect -re ".*root:~# "
send "ifconfig eth0 | grep 'inet addr' | cut -d ':' -f 2 | cut -d ' ' -f 1\r"
expect eof
send "\x1b\r"
expect "telnet>"
send "q\r"
puts "Address is $IPADDR"
EOF
}
运行此功能,我在屏幕上看到ip地址,但未捕获到变量SSH_IP
中。
我需要在两个方面提供帮助:
1.我该怎么做,以使SSH_IP
包含IP地址。
2.如何使expect
默默地完成所有这些操作并返回结果?
如果还有其他方法可以实现同一目标,请致电给我。
答案 0 :(得分:0)
这是期望的PITA领域之一:捕获命令输出。您将要执行以下操作:
function get_ip(){
# pass the shell function params via the environment, so we can quote the expect script
host=$1 port=$2 expect << 'EOF'
# use `log_user` and `spawn -noecho` to stop output to stdout
log_user 0
spawn -noecho telnet $env(host) $env(port)
expect -ex "Escape character is '^]'."
send "\r"
expect "login: "
send "root\r"
expect "root:~# "
send "ifconfig eth0\r" # expect can parse the output, don't need a pipeline
expect -re "(.*)root:~# " # note the captured part
set ip_addr [regexp -inline {inet addr:(\S+)} $expect_out(1,string)]
puts "Address is $ip_addr"
send "\x1b\r"
expect "telnet>"
send "q\r"
# NOW you expect eof
expect eof
EOF
}
我们甚至可以使用Expect模式捕获它:
send "ifconfig eth0\r"
expect -re ".*inet addr:(\S+).*root:~# "
puts "Address is $expect_out(1,string)"
答案 1 :(得分:0)
我决定选择tmux
,而不是expect
。这是我的解决方法
#! /bin/env bash
WINDOW_NAME=TELNET
DEBUG=
function dbbg(){
[[ "$DEBUG" ]] && echo "DEBUG: $@"
}
function cleanup(){
[[ "$DEBUG" ]] || tmux kill-window -t ${WINDOW_NAME} > /dev/null 2>&1
}
trap cleanup EXIT
if [ $# -eq 0 ]
then
echo "Usage $(basename $0) <telnet ip> <telnet port>"
exit 0
fi
# Start the work with sessions
tmux has-session 2>/dev/null
if [ "$?" -eq 1 ]
then
dbbg "No Session found. Creating and configuring."
tmux new-session -d
else
dbbg "Session found."
fi
tmux has-session -t :${WINDOW_NAME} 2>/dev/null
if [ "$?" -eq 1 ]
then
dbbg "No window found. Creating a window named ${WINDOW_NAME}"
tmux new-window -d -n ${WINDOW_NAME}
else
dbbg "Window found."
fi
dbbg "connecting to tmux ip: $1 port: $2"
tmux send-keys -t :${WINDOW_NAME} "telnet $1 $2" Enter
sleep 2
answer="$(tmux capture-pane -t :${WINDOW_NAME} -p | sed '/^$/d' | tail -n 1)"
dbbg $answer
if [ "$answer" != "Escape character is '^]'." ]
then
echo "Telnet is occupied at the moment, try later"
exit 1
fi
tmux send-keys -t :${WINDOW_NAME} Enter
sleep 2
answer="$(tmux capture-pane -t :${WINDOW_NAME} -p | sed '/^$/d' | tail -n 1)"
dbbg $answer
if [ "$answer" == "login:" ]
then
dbbg "Inputing user"
tmux send-keys -t :${WINDOW_NAME} "root" Enter
sleep 2
fi
tmux send-keys -t :${WINDOW_NAME} "ifconfig eth0 | grep 'inet addr' | cut -d ':' -f 2 | cut -d ' ' -f 1" Enter
sleep 2
ip_addr="$(tmux capture-pane -t :${WINDOW_NAME} -p | sed '/^$/d' | tail -n 2 | head -n 1)"
tmux send-keys -t :${WINDOW_NAME} C-]
sleep 2
tmux send-keys -t :${WINDOW_NAME} "q" Enter
echo $ip_addr