首頁  >  文章  >  運維  >  詳解shell實現SSH自動登陸

詳解shell實現SSH自動登陸

藏色散人
藏色散人轉載
2020-01-25 16:44:193677瀏覽

詳解shell實現SSH自動登陸

前言

公司開發使用docker,每次登陸自己開發機總要輸入ssh user_name@ip_string,然後再確認輸入password#,手快了還常常會輸錯。身為一個懶人,肯定要找一個取巧的方式,查看了下ssh命令,由於它要進行一次跟伺服器的加密交互,所以沒有直接附帶密碼登陸的選項,只好作罷。

推薦:《Linux教學》

前些天在同事進行技術分享時,看到他竟然只輸入了一行指令./test. sh就成功登陸了開發機,甚是驚異,於是回來搜尋研究了一下,遂成此文。

shell腳本基礎

在編寫ssh自動登陸腳本之前,先說一下shell腳本的基礎,此基礎不是一些語法什麼的,網路上到處都是,這裡總結了一下shell腳本的運作機制~

shell腳本的運作方式

#首先要說shell的幾種啟動方式,正是踩了腳本啟動的坑,才使用原來十分鐘就搞定的腳本,花了兩個小時才搞定。同時也使得我們運行shell,知其所以然。

透過檔案名稱執行

shell腳本可以直接透過檔案名稱執行,需要注意的是檔案需要執行權限。透過sudo chmod x ./file_name.sh 來為檔案新增執行權限;

指定腳本解釋器來執行檔案

我們常用的sh file_name.sh 是指定了腳本解釋器/bin/sh來解釋執行腳本;常見的腳本解釋器還有:/bin/bash等等,我們可以使用ls -l /bin/*sh指令來查看目前可用的腳本解釋器;

使用. ./file_name或source指令執行腳本

這種方式不會像前兩種方式一樣fork一個子程序去執行腳本,而是使用當前shell環境執行,用於.bashrc或.bash_profile被修改的時候,我們不必重啟shell或者重新登入系統,就能使目前的變更生效。

shebang

我們寫一個shell腳本時,總是習慣在最前面加上一行#!/binbash,它就是腳本的shebang,至於為什麼叫這麼個奇怪的名字,C語言和Unix的開發者丹尼斯·里奇稱它為可能是類似於"hash-bang"的英國風描述性文字;

貼一段wiki上的解釋:

在電腦科學中,Shebang是一個由井號和嘆號構成的字串行,其出現在文字檔案的第一行的前兩個字元。在檔案中存在Shebang的情況下,類別Unix作業系統的程式載入器會分析Shebang後的內容,將這些內容作為解釋器指令,並呼叫指令,並將載有Shebang的檔案路徑作為該解釋器的參數。

簡單的說,它指示了此腳本運行時的解釋器,所以,使用檔案名稱直接執行shell腳本時,必須帶上shebang; 此外,我們還可以在shebang後面直接附加選項,執行時我們預設使用選項執行;

如test.sh的shebang為#!/bin/sh -x,那我們執行腳本時:

./test.sh hello

相當於:

bin/sh -x ./test.sh hello;

而寫一個ssh自動登陸腳本,需要用到的shebang(解釋器)為/usr/bin/expect;

需要注意的是:在指定腳本解釋器來執行腳本時,shebang會被指定的腳本解釋器覆蓋,即優先使用指定的腳本解釋器來執行腳本(習慣性地用sh ./test.sh卻提示command not found)

##expect解釋器

expect是一個能實現自動和互動式任務的解釋器,它也能解釋常見的shell語法命令,其特色在以下幾個命令:

#spawn指令:

spawn command指令會fork一個子程序去執行command指令,然後在此子行程中執行後面的指令;

在ssh自動登陸腳本中,我們使用spawn ssh user_name@ip_str,fork一個子程序執行ssh登陸指令;

expect指令:

expect指令是expect解釋器的關鍵指令,它的一般用法為expect "string",即期望取得到string字串,可在在string字串裡使用* 等通配符;

string與命令列傳回的資訊相符後,expect會立刻向下執行腳本;

set timeout指令:

set timeout n指令將expect指令的等待逾時時間設為n秒,在n秒內還沒有取得到其期待的指令,expect 為false,腳本會繼續往下執行;

send指令:

send指令的一般用法為send "string",它們會我們平常輸入指令一樣向命令列輸入一則訊息,當然不要忘了在string後面加上上\r 表示輸入回車;

interact指令:

interact命令很简单,执行到此命令时,脚本fork的子进程会将操作权交给用户,允许用户与当前shell进行交互;

完成脚本

以下是一个完成版的脚本 test.sh:

#!/usr/bin/expect                   // 指定shebang
set timeout 3                       // 设定超时时间为3秒
spawn ssh user_name@172.***.***.*** // fork一个子进程执行ssh命令
expect "*password*"                 // 期待匹配到 'user_name@ip_string's password:' 
send "my_password\r"                // 向命令行输入密码并回车
send "sudo -s\r" 
send "cd /data/logs\r"              // 帮我切换到常用的工作目录
interact                            // 允许用户与命令行交互

执行 sudo chmod +x ./test.sh命令给shell脚本添加执行权限;

运行 ./test.sh命令,一键登陆成功!

简单的几个命令,,搭配起来解决了与命令行的交互问题后,很多复杂的功能也不在话下了~

alias别名

脚本完成了,可是还是有些小瑕疵:

输入./file_name.sh命令太长。。。

只能在脚本目录中才能执行,不然使用绝对路径输出的命令更长。

这里我们想到了linux的alias命令:

alias命令:

alias命令使用方式为 alias alias_name="ori_command",将alias_name设置为ori_command的别名,这样我们输入执行alias_name,就相当于执行了ori_command;

可是,我们会发现,当你关闭当前shell后,再打开一个shell窗口,再使用alias_name,系统提示command not found;

有没有能保持命令的方式呢?编辑bash_profile文件。

bash_profile文件

我们编辑bash_profile文件,此文件会在终端窗口创建的时候首先执行一次,所以可以帮我们再设置一次别名;

执行命令vim ~./bash_profile,在文件内部添加:

alias alias_name="/root_dir/../file_name.sh

保存后,再使用 . ~./bash_profilesource ~./bash_profile 在当前脚本执行一遍设置别名命令,完成设置;

这样,我们无论在哪个目录,只要输入alias_name命令,回车,真正的一键登陆!

以上是詳解shell實現SSH自動登陸的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除