Linux 使用 bash 脚本自动化 telnet 会话
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7013137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
automating telnet session using bash scripts
提问by khan
I am working on automating some telnet related tasks, using Bash scripts. Once automated there will be no interaction of the user with telnet. (that is it will be totally automated)
我正在使用 Bash 脚本自动化一些与 telnet 相关的任务。一旦自动化,用户将不再与 telnet 交互。(也就是说它将完全自动化)
the scripts looks something like this:
脚本看起来像这样:
# 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.
There are 2 problems I am facing here:
我在这里面临两个问题:
How to execute the commands on the remote system from the script (without human interaction)?
From my experience with some test codes, I was able to deduce that when the telnet 10.1.1.1is executed, telnet goes into an interactive session and the subsequent lines of code in the script are executed on the local system. How can I run the lines of code on the remote system rather than the local one?
I am unable to get a log file for the activity in the telnet session on the local system. The stdout redirect I used makes a copy on the remote system (I do not want to perform a copy operation to copy the log to the local system). How can I achieve this functionality?
如何从脚本执行远程系统上的命令(无需人工交互)?
根据我使用一些测试代码的经验,我能够推断出,当执行telnet 10.1.1.1时,telnet 进入交互式会话,并且脚本中的后续代码行在本地系统上执行。如何在远程系统而不是本地系统上运行代码行?
我无法获取本地系统上 telnet 会话中活动的日志文件。我使用的 stdout 重定向在远程系统上进行了复制(我不想执行复制操作将日志复制到本地系统)。我怎样才能实现这个功能?
采纳答案by joemooney
Write an expect
script.
写一个expect
脚本。
Here is an example:
下面是一个例子:
#!/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
To run:
跑步:
./myscript.expect name user password
回答by TMS
Use ssh for that purpose. Generate keys without using a password and place it to .authorized_keys at the remote machine. Create the script to be run remotely, copy it to the other machine and then just run it remotely using ssh.
为此目的使用 ssh。在不使用密码的情况下生成密钥并将其放在远程机器上的 .authorized_keys 中。创建要远程运行的脚本,将其复制到另一台机器,然后使用 ssh 远程运行它。
I used this approach many times with a big success. Also note that it is much more secure than telnet.
我多次使用这种方法并取得了巨大成功。另请注意,它比 telnet 安全得多。
回答by thiton
While I'd suggest using expect, too, for non-interactive use the normal shell commands might suffice. Telnet accepts its command on stdin, so you just need to pipe or write the commands into it:
虽然我也建议使用 expect,但对于非交互式使用,普通的 shell 命令可能就足够了。Telnet 在 stdin 上接受其命令,因此您只需要将命令通过管道传输或写入其中:
telnet 10.1.1.1 <<EOF
remotecommand 1
remotecommand 2
EOF
(Edit: Judging from the comments, the remote command needs some time to process the inputs or the early SIGHUP is not taken gracefully by the telnet. In these cases, you might try a short sleep on the input:)
(编辑:从评论来看,远程命令需要一些时间来处理输入或早期的 SIGHUP 没有被 telnet 优雅地采用。在这些情况下,您可以尝试对输入进行短暂的睡眠:)
{ echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; } | telnet 10.1.1.1
In any case, if it's getting interactive or anything, use expect
.
在任何情况下,如果它变得交互式或任何东西,请使用expect
.
回答by str8
Play with tcpdump
or wireshark
and see what commands are sent to the server itself
使用tcpdump
或wireshark
查看发送到服务器本身的命令
Try this
尝试这个
printf (printf "$username\r\n$password\r\nwhoami\r\nexit\r\n") | ncat $target 23
Some servers require a delay with the password as it does not hold lines on the stack
某些服务器需要延迟密码,因为它不会在堆栈中保留行
printf (printf "$username\r\n";sleep 1;printf "$password\r\nwhoami\r\nexit\r\n") | ncat $target 23**
回答by biera
Telnet is often used when you learn HTTP protocol. I used to use that script as a part of my web-scraper:
学习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
let's say the name of the script is get-page.sh then:
假设脚本的名称是 get-page.sh 然后:
get-page.sh | telnet
will give you a html document.
会给你一个html文件。
Hope it will be helpful to someone ;)
希望它会对某人有所帮助;)
回答by A R
You can use expect scripts instaed of bash. Below example show how to telnex into an embedded board having no password
您可以使用期望脚本来代替 bash。下面的例子展示了如何 telnex 进入没有密码的嵌入式板
#!/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
回答by Nikhil
This worked for me..
这对我有用..
I was trying to automate multiple telnet logins which require a username and password. The telnet session needs to run in the background indefinitely since I am saving logs from different servers to my machine.
我试图自动化需要用户名和密码的多个 telnet 登录。telnet 会话需要无限期地在后台运行,因为我将来自不同服务器的日志保存到我的机器上。
telnet.sh automates telnet login using the 'expect' command. More info can be found here: http://osix.net/modules/article/?id=30
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 is used to create a background process for each of the telnet sessions by running telnet.sh. More information can be found in the comments section of the code.
sample_script.sh 用于通过运行 telnet.sh 为每个 telnet 会话创建后台进程。更多信息可以在代码的注释部分找到。
sample_script.sh
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)"
- Make sure there is no screen running in the backgroud by using the command 'screen -ls'.
- Read http://www.gnu.org/software/screen/manual/screen.html#Stuffto read more about screen and its options.
- '-p' option in sample_script.sh preselects and reattaches to a specific window to send a command via the ‘-X' option otherwise you get a 'No screen session found' error.
- 使用命令“screen -ls”确保后台没有屏幕在运行。
- 阅读 http://www.gnu.org/software/screen/manual/screen.html#Stuff以了解有关屏幕及其选项的更多信息。
- sample_script.sh 中的“-p”选项预选并重新附加到特定窗口以通过“-X”选项发送命令,否则您会收到“未找到屏幕会话”错误。
回答by shaman888
#!/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"
回答by grepit
Here is how to use telnet in bash shell/expect
以下是如何在 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 "'^]'."
回答by SAEED MAHMOOD ASLAM
Following is working for me... put all of your IPs you want to telnet in IP_sheet.txt
以下对我有用...将您要远程登录的所有 IP 放在 IP_sheet.txt 中
while true
read a
do
{
sleep 3
echo df -kh
sleep 3
echo exit
} | telnet $a
done<IP_sheet.txt