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

     2023-03-16     200

关键词:

【中文标题】使用 bash 脚本自动化远程登录会话【英文标题】:Automating telnet session using bash scripts 【发布时间】:2011-10-24 04:43:27 【问题描述】:

我正在使用 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 会话中活动的日志文件。我使用的标准输出重定向在远程系统上进行了复制(我不想执行复制操作将日志复制到本地系统)。我怎样才能实现这个功能?

【问题讨论】:

【参考方案1】:

编写一个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

【讨论】:

“期望”主要用于交互式会话。我想要的是一个自动化的非交互式会话。我面临的问题是我无法在远程系统上运行脚本(通过 telnet),因为 telnet 10.1.1.1 之后的所有行都在本地机器上执行,而不是在我的机器上执行访问。 正如 Thomas Telensky 指出的,根据您的需要,ssh 最终会更容易。但是 expect 可以是完全非交互式的。我假设您的意思是 telnet 之后的所有行都是您希望在远程计算机上执行的,在这种情况下,只需将它们作为发送命令添加到期望脚本并删除交互命令即可。但 ssh 更简单、更安全。 很公平。我将使用 expect 来完成这项任务。【参考方案2】:

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

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

【讨论】:

ssh 肯定比telnet 更安全,但是有些IP 设备就是不提供ssh 服务,而是依赖telnet 协议来使用设备。 telnet(程序)可以用作任何(或更实际地)基于文本的客户端/服务器连接的客户端。它可以用于简单的测试,例如 HTTP 和 IMAP。 @Tomas 的建议是将 Telnet(远程登录服务)的使用替换为 SSH。虽然他的评论是真实的,但这可能不是 OP 所要求的。 Rob,telnet 确实可用于连接到任何端口,但请参阅 OPs 问题 - 在他的上下文中,他只想将 telnet 用于 login(引用:“在远程系统上执行一些命令”)。为此目的使用 telnet 是非常危险的。 这不是对使用他现有脚本专门说“自动化一些与 telnet 相关的任务”的问题的答案。【参考方案3】:

虽然我也建议使用 expect,但对于非交互式使用,普通的 shell 命令可能就足够了。 telnet 在标准输入上接受它的命令,所以你只需要通过heredoc 管道或写入命令:

telnet 10.1.1.1 <<EOF
remotecommand 1
remotecommand 2
EOF

(编辑:从 cmets 判断,远程命令需要一些时间来处理输入,或者早期的 SIGHUP 没有被 telnet 优雅地采用。在这些情况下,您可以尝试短在输入上睡觉:)

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

在任何情况下,如果要进行互动或其他任何事情,请使用expect

【讨论】:

+1 sleep 像梦一样工作 ;-) 我还在两者之间添加了 | tee /dev/tty | 以在屏幕上进行完整会话;-) 就我而言,这是最有帮助的答案,但我必须添加echo -e "command\r"; 如何以非交互方式为 telnet 提供密码? echo "remotecommand 1"; echo "remotecommand 2"; sleep 1; | telnet 10.1.1.1 :这个例子符合我的要求。只想知道如果telnet失败我们如何添加错误检查并且shell脚本应该exit 1【参考方案4】:

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**

【讨论】:

新奇不是粗鲁的借口。请参阅常见问题解答***.com/faq。 并不是侮辱,更像是......我不知道,道歉。我只是不断看到人们使用期望命令作为解决方案。我只是想让人们意识到有一个更好的解决方案来理解你想要完成的事情。 expect 命令并没有告诉你它是如何工作的,它只是一个不知道的解决方法。它比没有更令人困惑。如有疑问,请前往源头。如果源不可用,并且如果它是网络协议,tcpdump,wireshark,窥探数据包并遵循命令流,您应该能够将一些东西放在一起工作知识。 如果你这么说 - 我是一名 Mathematica 程序员,所以你的回答和评论的实质对我来说是个谜。但我并不是唯一一个将“白痴”这个词解释为故意侮辱的人。我认为您需要在该网站上多花点时间,看看人们在这里的行为如何。【参考方案5】:

在学习 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文件。

希望对某人有所帮助;)

【讨论】:

最有帮助的评论!这实际上使您可以通过将命令置于循环中来自动发送命令 另一个帮助帖子blog.tonycode.com/tech-stuff/http-notes/… 单行等效项: echo "GET / HTTP/1.1"; echo "Host: www.example.com"; echo; sleep 1; | telnet www.example.com 80。请注意,一开始不需要 sleep(除非您使用 open 命令),最后只需要一个空 echo 和 sleep 1 而不是 2。 但是如果你需要做HTTPS请求,你应该使用netcat,也称为ncat或nc: echo "GET / HTTP/1.1"; echo "Host: example.com"; echo; sleep 1; | ncat --ssl example.com 443 非常有帮助。这将在屏幕上获得输出。无论如何我可以等待来自 telnet 的已知字符串,然后运行我的下一个命令,而不是 sleep?【参考方案6】:

您可以使用期望脚本来代替 bash。 下面的例子展示了如何连接到没有密码的嵌入式板

#!/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

【讨论】:

【参考方案7】:

这对我有用..

我试图自动化多个需要用户名和密码的 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 会话创建一个后台进程。更多信息可以在代码的 cmets 部分找到。

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)"
    使用 命令“屏幕-ls”。 读取 http://www.gnu.org/software/screen/manual/screen.html#Stuff阅读 有关屏幕及其选项的更多信息。 sample_script.sh 中的“-p”选项 预选并重新附加到特定窗口以通过以下方式发送命令 “-X”选项,否则会出现“未找到屏幕会话”错误。

【讨论】:

【参考方案8】:
#!/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"

【讨论】:

【参考方案9】:

这里是如何在 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 "'^]'."

【讨论】:

【参考方案10】:

以下对我有用... 把你想远程登录的所有IP都放在IP_sheet.txt中

while true
read a
do

    sleep 3
    echo df -kh
    sleep 3
    echo exit
 | telnet $a
done<IP_sheet.txt

【讨论】:

【参考方案11】:

获取 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

【讨论】:

【参考方案12】:

这是一个适用于扩展程序列表的解决方案。这只需要 bash - 上面的一些答案需要 expect 并且您可能无法指望安装 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

【讨论】:

【参考方案13】:

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

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

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

【讨论】:

远程服务器是否需要quitexit 或其他东西完全取决于另一端的内容。该命令被发送到远程服务器,而不是telnet 客户端本身(除了作为输出到另一端的输入)。也许您可以编辑以澄清这一点? @tripleee 谢谢,很高兴知道。当我在telnet 客户端中尝试telnet 时,我实际上很惊讶quit 没有使用^] 转义。我稍后会在答案中澄清这一点。您知道在使用telnet(或curl)时是否可以在脚本中退出客户端,而不依赖于服务器行为? 实际上,如果curl 遵循与传统telnet 相同的转义机制,我会感到非常惊讶,并且根据简短的实验,它似乎确实没有。 ***.com/questions/42347271/… 建议使用超时;该手册没有提到带外命令的任何内容。

远程登录 redis bash 脚本

】远程登录redisbash脚本【英文标题】:telnetredisbashscript【发布时间】:2013-10-3105:03:34【问题描述】:如何在bash脚本中从远程redis服务器上的telnet命令提取输出。我愿意:telnetremote-redis-ip6379LRANGEmylist0-1并将结果保存在变量中。我... 查看详情

如何使用 Expect 自动化 telnet 会话?

】如何使用Expect自动化telnet会话?【英文标题】:HowtoautomatetelnetsessionusingExpect?【发布时间】:2012-06-3007:44:44【问题描述】:我正在尝试编写一个期望脚本来自动化远程登录。这是我目前所拥有的。#!/usr/bin/expect#Testexpectscripttoteln... 查看详情

为 Telnet 会话创建脚本?

】为Telnet会话创建脚本?【英文标题】:CreatingascriptforaTelnetsession?【发布时间】:2010-10-1702:59:53【问题描述】:有谁知道创建脚本的简单方法,该脚本可以连接到远程登录服务器,执行一些常用的远程登录操作,然后注销?我正... 查看详情

图文教程自动登录expect脚本实例

...录远程机器,并且可以实现自动远程执行命令。当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时候只要知道对方机器的账号和密码就... 查看详情

6月份个人:修改windows系统多人使用多账号同时远程登陆并修改脚本自动生成每个用户登录日志。

第一步:打开运行输入gpedit.msc打开本地组策略编辑器选择管理模板->Windows组件->终端服务->会话->点击限制连接数量,再点击已启用,修改允许最大数量即可。第二步:新建用户。右键“此电脑”->管理->本地用户和... 查看详情

分发系统——expect

...录远程机器,并且可以实现自动远程执行命令。当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时候只要知道对方机器的账号和密码就... 查看详情

使用sshpass和ssh实现无密码自动远程登录

参考技术Alinux对linux进行登录可以使用ssh工具,但是在使用ssh的时候经常需要输入密码,因此需要安装sshpass工具,实现自动登录。使用命令登录远程服务器:为了解决每次登录都需要输入密码,ip地址等信息,可以自定义一个shel... 查看详情

在 PHP 登录脚本中使用会话和会话变量

】在PHP登录脚本中使用会话和会话变量【英文标题】:Usingsessions&sessionvariablesinaPHPLoginScript【发布时间】:2012-04-2306:47:12【问题描述】:我刚刚在PHP中创建了一个完整的登录和注册系统,但我的问题是我还没有使用任何会话。... 查看详情

如何在使用 Python 脚本登录时维护登录会话

】如何在使用Python脚本登录时维护登录会话【英文标题】:HowtomaintainloginsessionwhilelogginginusingPythonScript【发布时间】:2014-10-1303:34:28【问题描述】:我想使用python脚本登录Ideone.com,然后使用python脚本使用后续请求从我自己的帐户... 查看详情

如何在 bash 脚本中的流水线命令之间插入延迟。例如。猫文件 |远程登录 mail.domain.com 25

】如何在bash脚本中的流水线命令之间插入延迟。例如。猫文件|远程登录mail.domain.com25【英文标题】:Howtoinsertadelaybetweenpipeliningcommandsinabashscript.E.g.catfile|telnetmail.domain.com25【发布时间】:2013-10-1923:01:58【问题描述】:我有一个创... 查看详情

如何使用 bash 脚本在远程机器上运行命令?

】如何使用bash脚本在远程机器上运行命令?【英文标题】:Howtoruncommandsonremotemachineusingbashscript?【发布时间】:2016-11-0103:41:19【问题描述】:我正在尝试在远程机器上运行以下命令,但没有执行任何操作,谁能指出以下脚本的问... 查看详情

脚本_使用expect自动交互远程主机安装软件

#!bin/bash#功能:使用expect工具自动交互密码,远程到其它主机,安装httpd软件#作者:liusingbon#删除~/.ssh/known-hosts后,ssh远程任何主机,系统都会询问是否确认要连接到该主机rm-rf~/ssh/known_hostsexpect<<EOF #下一行开始,所有字符都按照指... 查看详情

以编程方式将 10 个用户登录到远程桌面会话

...题描述】:我正在尝试创建一个应用程序,该应用程序将使用RDP以编程方式登录10个用户。目的是自动登录这些用户,这样就不必手动进行了。我测试的第一台服务器(Server2012)运行良好。但是,我尝试了Server2008R2,它继 查看详情

如何创建一个 bash 脚本来检查 SSH 连接?

...脚本来检查SSH连接是否已启动。在实际创建密钥以供将来使用之前。【问题讨论】:通常,运行 查看详情

使用脚本保持远程会话运行直到程序结束?

】使用脚本保持远程会话运行直到程序结束?【英文标题】:Keeparemoteseesionrunninguntiltheendofaprogramusingascript?【发布时间】:2020-07-0412:17:44【问题描述】:我想在Linux服务器A上运行一个程序。Linux服务器B可以监控服务器A的功率指标... 查看详情

Bash 脚本使用 ssh 和日期在远程系统上设置坐标世界时

】Bash脚本使用ssh和日期在远程系统上设置坐标世界时【英文标题】:BashscriptsetCoordinateUniversalTimeonremotesystemusingsshanddate【发布时间】:2019-05-0912:40:48【问题描述】:我有一个bash脚本,它尝试在另一台机器上同步时间。这不是我... 查看详情

分发系统介绍expect脚本远程执行命令expect脚本远程传递参数expect脚本传递参数(代码片段)

...录远程机器,并且可以实现自动远程执行命令。当然若是使用不带密码的密钥验证同样可以实现自动登录和自动远程执行命令。但当不能使用密钥验证的时候,我们就没有办法了。所以,这时候只要知道对方机器的账号和密码就... 查看详情

golddata如何采集需要登录/会话的数据?(代码片段)

概要本文将介绍使用GoldData半自动登录功能,来采集需要登录网站的数据。GoldData半自动登录功能,就是指通过脚本来执行登录,如果需要验证码或者其它内容需要人工输入时,可以通过收发邮件来执行登录流程。下载例子为了... 查看详情