前言
公司開發使用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.s
h 是指定了腳本解釋器/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_profile
或source ~./bash_profile
在当前脚本执行一遍设置别名命令,完成设置;
这样,我们无论在哪个目录,只要输入alias_name
命令,回车,真正的一键登陆!
以上是詳解shell實現SSH自動登陸的詳細內容。更多資訊請關注PHP中文網其他相關文章!