使用bash脚本自动执行telnet会话

时间:2011-08-10 15:10:15

标签: linux bash telnet

我正在使用Bash脚本自动执行一些与telnet相关的任务。 一旦自动化,用户就不会与telnet进行交互。 (即它将完全自动化)

脚本看起来像这样:

# execute some commands on the local system
# access a remote system with an IP address: 10.1.1.1 (for example)

telnet 10.1.1.1

# execute some commands on the remote system
# log all the activity (in a file) on the Local system
# exit telnet
# continue on with executing the rest of the script.

我在这面面有两个问题:

  1. 如何从脚本执行远程系统上的命令(没有人工交互)?

    根据我对一些测试代码的经验,我能够推断出当执行 telnet 10.1.1.1 时,telnet进入交互式会话并执行脚本中的后续代码行在本地系统上。如何在远程系统而不是本地代码上运行代码行?

  2. 我无法在本地系统上的telnet会话中获取活动的日志文件。我使用的stdout重定向在远程系统上创建一个副本(我不想执行复制操作将日志复制到本地系统)。如何实现此功能?

13 个答案:

答案 0 :(得分:74)

虽然我建议使用expect,但对于非交互式使用,正常的shell命令可能就足够了。 Telnet在stdin上接受它的命令,所以你只需要将命令管道或写入其中:

telnet 10.1.1.1 <<EOF
remotecommand 1
remotecommand 2
EOF

(编辑:从评论中判断,远程命令需要一些时间来处理输入,或者telnet没有正常使用早期的SIGHUP。在这些情况下,你可能会尝试在输入上进行短暂的睡眠:)

{ echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; } | telnet 10.1.1.1

无论如何,如果它正在进行互动或其他任何事情,请使用expect

答案 1 :(得分:71)

编写expect脚本。

以下是一个例子:

#!/usr/bin/expect

#If it all goes pear shaped the script will timeout after 20 seconds.
set timeout 20
#First argument is assigned to the variable name
set name [lindex $argv 0]
#Second argument is assigned to the variable user
set user [lindex $argv 1]
#Third argument is assigned to the variable password
set password [lindex $argv 2]
#This spawns the telnet program and connects it to the variable name
spawn telnet $name 
#The script expects login
expect "login:" 
#The script sends the user variable
send "$user "
#The script expects Password
expect "Password:"
#The script sends the password variable
send "$password "
#This hands control of the keyboard over to you (Nice expect feature!)
interact

运行:

./myscript.expect name user password

答案 2 :(得分:40)

学习HTTP协议时经常使用Telnet。我以前使用该脚本作为我的网络刮刀的一部分:

echo "open www.example.com 80" 
sleep 2 
echo "GET /index.html HTTP/1.1" 
echo "Host: www.example.com" 
echo 
echo 
sleep 2

让我们说脚本的名称是get-page.sh然后:

get-page.sh | telnet

会给你一个html文件。

希望对某人有所帮助;)

答案 3 :(得分:10)

这对我有用..

我试图自动化多个需要用户名和密码的telnet登录。 telnet会话需要无限期地在后台运行,因为我将日志从不同的服务器保存到我的机器。

telnet.sh使用'expect'命令自动执行telnet登录。更多信息可以在这里找到:http://osix.net/modules/article/?id=30

<强> telnet.sh

#!/usr/bin/expect
set timeout 20
set hostName [lindex $argv 0]
set userName [lindex $argv 1]
set password [lindex $argv 2]

spawn telnet $hostName

expect "User Access Verification"
expect "Username:"
send "$userName\r"
expect "Password:"
send "$password\r";
interact

sample_script.sh用于通过运行telnet.sh为每个telnet会话创建后台进程。更多信息可以在代码的评论部分找到。

<强> sample_script.sh

#!/bin/bash
#start screen in detached mode with session-name 'default_session' 
screen -dmS default_session -t screen_name 
#save the generated logs in a log file 'abc.log' 
screen -S default_session -p screen_name -X stuff "script -f /tmp/abc.log $(printf \\r)"
#start the telnet session and generate logs
screen -S default_session -p screen_name -X stuff "expect telnet.sh hostname username password $(printf \\r)"
  1. 使用。确保背景中没有正在运行的屏幕 命令'screen -ls'。
  2. http://www.gnu.org/software/screen/manual/screen.html#Stuff阅读 更多关于屏幕及其选项。
  3. sample_script.sh中的
  4. ' - p'选项 预选并重新连接到特定窗口以通过发送命令 “ - X”选项,否则您会收到“未找到屏幕会话”错误。

答案 4 :(得分:2)

您可以使用expect脚本而不是bash。 下面的示例显示如何telnet到没有密码的嵌入式主板

#!/usr/bin/expect

set ip "<ip>"

spawn "/bin/bash"
send "telnet $ip\r"
expect "'^]'."
send "\r"
expect "#"
sleep 2

send "ls\r"
expect "#"

sleep 2
send -- "^]\r"
expect "telnet>"
send  "quit\r"
expect eof

答案 5 :(得分:2)

以下为我工作...... 将您想要的所有IP放在IP_sheet.txt

while true
read a
do
{
    sleep 3
    echo df -kh
    sleep 3
    echo exit
} | telnet $a
done<IP_sheet.txt

答案 6 :(得分:1)

为此目的使用ssh。不使用密码生成密钥,并将其放置在远程计算机上的.authorized_keys。创建要远程运行的脚本,将其复制到另一台计算机,然后使用ssh远程运行它。

我多次使用这种方法取得了巨大成功。另请注意,比telnet更安全。

答案 7 :(得分:1)

#!/bin/bash
ping_count="4"
avg_max_limit="1500"
router="sagemcom-fast-2804-v2"
adress="192.168.1.1"
user="admin"
pass="admin"

VAR=$(
expect -c " 
        set timeout 3
        spawn telnet "$adress"
        expect \"Login:\" 
        send \"$user\n\"
        expect \"Password:\"
        send \"$pass\n\"
        expect \"commands.\"
        send \"ping ya.ru -c $ping_count\n\"
        set timeout 9
        expect \"transmitted\"
        send \"exit\"
        ")

count_ping=$(echo "$VAR" | grep packets | cut -c 1)
avg_ms=$(echo "$VAR" | grep round-trip | cut -d '/' -f 4 | cut -d '.' -f 1)

echo "1_____ping___$count_ping|||____$avg_ms"
echo "$VAR"

答案 8 :(得分:0)

以下是如何在bash shell / expect中使用telnet

#!/usr/bin/expect
# just do a chmod 755 one the script
# ./YOUR_SCRIPT_NAME.sh $YOUHOST $PORT
# if you get "Escape character is '^]'" as the output it means got connected otherwise it has failed

set ip [lindex $argv 0]
set port [lindex $argv 1]

set timeout 5
spawn telnet $ip $port
expect "'^]'."

答案 9 :(得分:0)

用于获取CISCO服务器版本的脚本:

#!/bin/sh

servers='
192.168.34.1
192.168.34.3
192.168.34.2
192.168.34.3
'
user='cisco_login'
pass='cisco_password'

show_version() {
host=$1
expect << EOF
set timeout 20
set host $host
set user $user
set pass $pass
spawn telnet $host
expect "Username:"
send "$user\r"
expect "Password:"
send "$pass\r"
expect -re ".*#"
send "show version\r"
expect -re ".*-More-.*"
send " "
expect -re ".*#"
send "exit\r"
EOF
}

for ip in $servers; do
  echo '---------------------------------------------'
  echo "$ip"
  show_version $ip | grep -A3 'SW Version'
done

答案 10 :(得分:0)

这是一个适用于扩展程序列表的解决方案。这只需要 bash - 上面的一些答案需要 expect,您可能无法指望安装。

#!/bin/bash

declare -a  Extenders=("192.168.1.48" "192.168.1.50" "192.168.1.51") 
# "192.168.1.52" "192.168.1.56" "192.168.1.58" "192.168.1.59" "192.168.1.143")
sleep 5
# Iterate the string array using for loop
for val in ${Extenders[@]}; do
   { sleep 0.2; echo "root"; sleep 0.2; echo "ls"; sleep 0.2; }  | telnet $val
done

答案 11 :(得分:0)

@thiton 的 answer 很有帮助,但我想避免使用 sleep 命令。 telnet 也没有退出交互模式,所以我的脚本卡住了。

我通过使用 curl 发送 telnet 命令(似乎在等待响应)并明确告诉 telnet 像这样退出来解决了这个问题:

curl telnet://10.1.1.1:23 <<EOF
remotecommand 1
remotecommand 2
quit
EOF

答案 12 :(得分:-3)

tcpdumpwireshark一起玩,看看哪些命令发送到服务器本身

试试这个

printf (printf "$username\r\n$password\r\nwhoami\r\nexit\r\n") | ncat $target 23

某些服务器需要使用密码延迟,因为它不会在堆栈中保留行

printf (printf "$username\r\n";sleep 1;printf "$password\r\nwhoami\r\nexit\r\n") | ncat $target 23**