从shell脚本生成交互式telnet会话

11

我正在尝试编写一个脚本,以便我可以登录到一个具有48个端口的控制台服务器上,以便我可以快速确定哪些设备连接到了每条串行线路。

基本上,我想要能够有一个脚本,给定主机/端口列表,可以 telnet 到列表中的第一个设备并将我留在交互模式下,以便我可以登录并确认设备,然后当我关闭 telnet 会话时,连接到列表中的下一个会话。

我遇到的问题是,如果我在可执行的 bash 脚本内部启动 telnet 会话,则会话立即终止,而不是等待输入。

例如,给定以下代码:

$ cat ./telnetTest.sh
#!/bin/bash

while read line
do
        telnet $line
done
$

当我运行命令'echo "hostname" | testscript.sh'时,我收到以下输出:

$ echo "testhost" | ./telnetTest.sh
Trying 192.168.1.1...
Connected to testhost (192.168.1.1).
Escape character is '^]'.
Connection closed by foreign host.
$

有没有办法停止telnet会话自动关闭?

9个回答

7

您需要将终端输入重定向到 telnet 进程。这应该是 /dev/tty。因此,您的脚本将如下所示:

#!/bin/bash

for HOST in `cat`
do
  echo Connecting to $HOST...
  telnet $HOST </dev/tty
done

5

我认为您应该查看 expect 程序。它在所有现代 Linux 发行版中都存在。下面是一些示例脚本:

#!/usr/bin/expect -f
spawn telnet $host_name
expect {
   "T0>"                {}
   -re "Connection refused|No route to host|Invalid argument|lookup failure"
                        {send_user "\r******* connection error, bye.\n";exit}
   default              {send_user "\r******* connection error (telnet timeout),
 bye.\n";exit}
}
send "command\n"
expect -timeout 1 "something"

spawn 命令用于启动远程登录程序(如telnet、ssh、netcat等)。

expect 命令用于从远程会话中获取期望的结果。

send 命令用于发送命令。

send_user 命令用于向标准输出打印注释。


1

使用Shell脚本示例Telnet到服务器:

Test3.sh文件:

#!/bin/sh

#SSG_details is file from which script will read ip adress and uname/password
#to telnet.

SSG_detail=/opt/Telnet/SSG_detail.txt

cat $SSG_detail | while read ssg_det ; do

   ssg_ip=`echo $ssg_det|awk '{print $1}'`
   ssg_user=`echo $ssg_det|awk '{print $2}'`
   ssg_pwd=`echo $ssg_det|awk '{print $3}'`


   echo " IP to telnet:" $ssg_ip
   echo " ssg_user:" $ssg_user
   echo " ssg_pwd:" $ssg_pwd

   sh /opt/Telnet/Call_Telenet.sh $ssg_ip $ssg_user $ssg_pwd 

done


exit 0

Call_Telenet.sh脚本如下:

#!/bin/sh

DELAY=1 
COMM1='config t'                 #/* 1st commands to be run*/
COMM2='show run'
COMM3=''
COMM4=''
COMM5='exit'
COMM6='wr'
COMM7='ssg service-cache refresh all'
COMM8='exit'                     #/* 8th command to be run */


telnet $1 >> $logfile 2>> $logfile |&
sleep $DELAY
echo -p $2 >> $logfile 2>> $logfile
sleep $DELAY
echo -p $3 >> $logfile 2>> $logfile
sleep $DELAY
echo -p $4 >> $logfile 2>> $logfile
sleep $DELAY
echo -p $5 >> $logfile 2>> $logfile
sleep $DELAY

sleep $DELAY
sleep $DELAY
sleep $DELAY
echo -p $COMM7 >> $logfile 2>> $logfile
sleep $DELAY
echo -p $COMM8 >> $logfile 2>> $logfile
sleep $DELAY

exit 0

按照以下方式运行上述文件:

$> ./test3.sh 

1

谢谢Dave - 我漏掉了TTY重定向。

对于那些感兴趣的人,我使用的完整解决方案:

#!/bin/bash

TTY=`tty` # Find out what tty we have been invoked from.
for i in `cat hostnames.csv` # List of hosts/ports
do
        # Separate port/host into separate variables
        host=`echo $i | awk -F, '{ print $1 }'`
        port=`echo $i | awk -F, '{ print $2 }'`
        telnet $host $port < $TTY # Connect to the current device
done

0
如果您的环境是基于X11的,一种可能性是打开一个运行telnet的xterm:
xterm -e telnet $host $port

xterm 中的操作是交互式的,直到 xterm 终止,shell 脚本才会停止。


0
也许你可以尝试使用bash -i命令来强制会话进入交互模式。

0
你示例中的问题在于你把脚本(以及间接地 telnet)的输入连接到了 echo 的输出上。因此,在 echo 完成并启动 telnet 后,就无法再读取更多的输入了。一个简单的解决方法是用 { echo "testhost"; cat; } 替换 echo "testhost"
编辑: telnet 似乎不喜欢从管道中接收输入。但是,netcat 可以,并且可能更适合这种情况。

0

@muz 我有一个只支持ssh而不支持telnet的设置,所以我无法测试你的问题是否与telnet有关,但运行以下脚本可以成功地登录到不同的机器并要求输入密码。

for i in adele betty
do
ssh all@$i
done

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接