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

Posted

技术标签:

【中文标题】从 shell 脚本生成交互式 telnet 会话【英文标题】:Spawning an interactive telnet session from a shell script 【发布时间】:2010-09-11 04:17:16 【问题描述】:

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

基本上我希望能够有一个脚本,给定主机/端口列表,远程登录到列表中的第一个设备,并让我处于交互模式,以便我可以登录并确认设备,然后当我关闭 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 会话的方法?

【问题讨论】:

【参考方案1】:

您需要将终端输入重定向到telnet 进程。这应该是/dev/tty。所以你的脚本看起来像:

#!/bin/bash

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

【讨论】:

【参考方案2】:

我认为你应该看看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 等)

expext 命令用于...嗯.. 期待远程会话中的某些内容

发送 - 发送命令

send_user - 将 cmets 打印到标准输出

【讨论】:

【参考方案3】:

感谢 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

【讨论】:

【参考方案4】:

使用 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 

【讨论】:

【参考方案5】:

也许您可以尝试 bash -i 强制会话处于交互模式。

【讨论】:

【参考方案6】:

您的示例中的问题是您将脚本的输入(以及telnet 的间接输入)链接到echo 的输出。所以在完成echo 并启动telnet 之后,就没有更多的输入要读取了。一个简单的解决方法是将echo "testhost" 替换为 echo "testhost"; cat;

编辑:telnet 似乎不喜欢从管道中获取输入。但是,netcat 确实适用于这种情况。

【讨论】:

【参考方案7】:

@muz 我有一个 ssh 设置,没有 telnet,所以我无法测试您的问题是否与 telnet 相关,但是运行以下脚本将我连续记录到不同的机器上,要求输入密码。

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

【讨论】:

【参考方案8】:

如果您的环境是基于 X11 的,则可以打开一个运行 telnet 的 xterm:

xterm -e telnet $host $port

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

【讨论】:

【参考方案9】:

试试这些链接。

http://planetozh.com/blog/2004/02/telnet-script/

http://www.unix.com/unix-dummies-questions-answers/193-telnet-script.html

#!/bin/sh
( echo open hostname
sleep 5
echo username
sleep 1
echo password
sleep 1
echo some more output, etc. ) | telnet

他们为我工作:D

【讨论】:

以上是关于从 shell 脚本生成交互式 telnet 会话的主要内容,如果未能解决你的问题,请参考以下文章

linux通过shell脚本实现telnet交互式自动化

Telnet 从守护进程运行时无法正常运行

管道到头部导致从 python 调用的 shell 脚本中的管道损坏

将 telnet 会话记录为后台进程

使用 bash 脚本自动化远程登录会话

有没有办法将 telnet 会话输出作为邮递员测试脚本的一部分?