【问题标题】:extract ip address of eth0 from a telnet session从 telnet 会话中提取 eth0 的 IP 地址
【发布时间】:2023-03-30 08:40:01
【问题描述】:

我需要自动化处理远程设备的流程,

步骤如下

  1. 远程登录
  2. 输入用户名
  3. ifconfig eth0 | grep 'inet 地址' |剪切 -d ':' -f 2 |剪切 -d ' ' -f 1
  4. 记下显示的 ip 并使用该 ip 地址执行其余过程。

已知 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 默默地做这一切并返回结果?

如果有其他方法可以达到同样的目标,请告诉我。

【问题讨论】:

  • 旁注 - eth0 已经消失了一段时间,所以硬编码看起来......乐观。该命令在我的 Linux 机器上返回空白,这既是因为 eth0 不存在,也是因为如果我选择现有接口,inet addr 不会出现在输出中。

标签: bash shell expect


【解决方案1】:

这是期待 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
}

我们甚至可以使用期望模式来捕获它:

        send "ifconfig eth0\r"
        expect -re ".*inet addr:(\S+).*root:~# "
        puts "Address is $expect_out(1,string)"

Tcl 命令文档:https://tcl.tk/man/tcl8.6/TclCmd/contents.htm

【讨论】:

  • 谢谢你的回答,但这仍然给我一个空字符串。
【解决方案2】:

我决定使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    相关资源
    最近更新 更多