2011-08-10 54 views
57

我正在使用Bash腳本自動化一些telnet相關任務。 一旦自動化,用戶將不會與telnet交互。 (這是它會完全自動化)使用bash腳本自動化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. 

有2個問題,我在這裏面臨:

  1. 如何執行的命令從腳本遠程系統(沒有人際交互)?

    根據我對某些測試代碼的經驗,我能夠推斷出當執行telnet 10.1.1.1時,telnet進入交互式會話,腳本中的後續代碼行在本地系統上執行。我如何在遠程系統而不是本地系統上運行代碼行?

  2. 我無法獲得本地系統上telnet會話中活動的日誌文件。我使用的stdout重定向在遠程系統上創建了一個副本(我不想執行將日誌複製到本地系統的複製操作)。我怎樣才能實現這個功能?

回答

60

編寫一個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 two you (Nice expect feature!) 
interact 
+1

'expect'主要用於交互式會話。我想要的是一個自動化的非交互式會話。我遇到的問題是我無法在遠程系統上運行腳本(通過telnet),因爲_telnet 10.1.1.1_後面的所有行都在本地機器上執行,而不是在我正在訪問的機器上執行。 – khan

+1

正如Thomas Telensky指出的那樣,根據您的需要ssh最終更容易。但期望可以完全不互動。我假定你的意思是在telnet之後的所有行都是你想在遠程機器上執行的那種情況,只需將它們添加到expect腳本中作爲發送命令並刪除交互命令即可。但是ssh更簡單也更安全。 – joemooney

+1

夠公平的。我將使用期望來完成這項任務。 – khan

1

爲目的使用SSH。生成密鑰而不使用密碼並將其放置在遠程計算機上的.authorized_keys。創建要遠程運行的腳本,將其複製到另一臺機器,然後使用ssh遠程運行它。

我多次使用這種方法取得了巨大成功。還要注意的是它比telnet更安全

+1

'ssh'肯定比'telnet'更安全,但一些IP設備不提供'ssh'服務並依靠' telnet協議來使用設備。 – fduff

+2

telnet(程序)可以用作ANY(或更實際上最基本的)基於文本的客戶端/服務器連接的客戶端。它可以用於簡單測試,例如HTTP和IMAP。 @Tomas的建議是用SSH替換Telnet(遠程登錄服務)的使用。儘管他的評論是真實的,但這可能不是OP要求的。 –

+0

Rob,telnet確實可以用來連接到任何端口,但是看到OPs問題 - 在他的上下文中,他希望僅將telnet用於* login *(引用:*「在遠程系統上執行一些命令」*)。爲此目的使用telnet是非常危險的。 – TMS

60

雖然我建議使用expect,但對於非交互式使用,正常的shell命令可能就足夠了。遠程登錄接受它的標準輸入命令,所以你只需要管道或命令寫進去:

telnet 10.1.1.1 <<EOF 
remotecommand 1 
remotecommand 2 
EOF 

(編輯:從評論來看,遠程命令需要一些時間來處理輸入或早期SIGHUP是不是由正常的telnet拍攝。在這種情況下,你可以嘗試輸入:)

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

在任何情況下很短的睡眠,如果它變得互動或任何東西,使用expect

+2

這不起作用,因爲您關閉了與EOF的連接。 – TMS

+4

+1爲'sleep'和支撐表情 – vyom

+1

+1'sleep'像夢一樣工作;-)我也加了'| tee/dev/tty |'在屏幕之間進行完整會話;-) – paluh

-3

tcpdumpwireshark,看看玩什麼命令發送到服務器本身

試試這個

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

某些服務器需要與密碼的延遲,因爲它沒有將紙疊

上線當你學習HTTP協議
printf (printf "$username\r\n";sleep 1;printf "$password\r\nwhoami\r\nexit\r\n") | ncat $target 23** 
+5

新奇不是無禮的藉口。請參閱常見問題http://stackoverflow.com/faq。 – Verbeia

+1

並不意味着是侮辱,更像是......我不知道,道歉。我只是繼續看到人們使用expect命令作爲解決方案。我只是希望人們認識到有一個更好的解決方案來理解你想要完成的事情。 expect命令不會告訴你它的工作方式,它只是一個不知道的解決方法。那就更困惑了。如有疑問,請去信息源。如果源不可用,並且它的網絡協議tcpdump wireshark窺探數據包並遵循命令流程,則應該能夠將具有工作知識的東西放在一起。 – str8

+3

如果你這樣說 - 我是一個Mathematica程序員,所以你的回答和評論的實質對我來說是一個謎。但我並不孤單地解釋「白癡」一詞是故意侮辱的。我認爲你需要花更多時間在網站上看看人們在這裏的表現。 – Verbeia

37

的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文件。

希望對某人有所幫助;)

+1

最有用的評論!這實際上可以讓你自動發送命令,將它們放入循環中 –

+0

另一篇幫助文章http://blog.tonycode.com/tech-stuff/http-notes/making-http-requests-via-telnet – meurer

2

您可以使用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 
9

這個工作對我..

我試圖自動化需要用戶名和密碼多個Telnet登錄。由於我將來自不同服務器的日誌保存到我的機器,因此telnet會話需要無限期地在後臺運行。

telnet.sh自動使用 '預期' 命令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. 確保沒有使用 命令 '屏幕-ls' 的研究背景運行沒有屏幕。
  2. 閱讀 http://www.gnu.org/software/screen/manual/screen.html#Stuff閱讀 更多的屏幕和它的選項。
  3. sample_script.sh中的'-p'選項 預選並重新附加到特定窗口以通過 發送命令'-X'選項,否則您將得到'無屏幕會話找到'錯誤。
0
#!/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" 
0

這裏是如何使用telnet在bash shell中/期望

#!/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 "'^]'." 
0

以下是爲我工作... 把所有的IP地址,你想在IP_sheet.txt

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