我正在使用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.
我在这面面有两个问题:
如何从脚本执行远程系统上的命令(没有人工交互)?
根据我对一些测试代码的经验,我能够推断出当执行 telnet 10.1.1.1 时,telnet进入交互式会话并执行脚本中的后续代码行在本地系统上。如何在远程系统而不是本地代码上运行代码行?
我无法在本地系统上的telnet会话中获取活动的日志文件。我使用的stdout重定向在远程系统上创建一个副本(我不想执行复制操作将日志复制到本地系统)。如何实现此功能?
答案 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)"
答案 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)
与tcpdump
或wireshark
一起玩,看看哪些命令发送到服务器本身
试试这个
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**