公司开发使用docker,每次登录本身开发机总要输入 ssh user_name@ip_string
,而后再确认输入password
,手快了还常常会输错。做为一个懒人,确定要找一个取巧的方式,查看了下ssh命令,因为它要进行一次跟服务器的加密交互,因此没有直接附带密码登录的选项,只好做罢。html
前些天在同事进行技术分享时,看到他居然只输入了一行命令./test.sh
就成功登录了开发机,甚是惊异,因而回来搜索研究了一下,遂成此文。linux
在编写ssh自动登录脚本以前,先说一下shell脚本的基础,此基础不是一些语法什么的,网上处处都是,这里总结了一下shell脚本的运行机制~docker
首先要说一下shell的几种启动方式,正是踩了脚本启动的坑,才使用原来十分钟就搞定的脚本,花了两个小时才搞定。同时也使得咱们运行shell,知其因此然。shell
shell脚本能够直接经过文件名执行,须要注意的是文件须要执行权限。经过 sudo chmod +x ./file_name.sh
来给文件添加执行权限;vim
咱们经常使用的 sh file_name.sh
就是指定了脚本解释器 /bin/sh
来解释执行脚本;常见的脚本解释器还有:/bin/bash
等,咱们可使用ls -l /bin/*sh
命令来查看当前可用的脚本解释器;bash
这种方式不会像前两种方式同样fork一个子进程去执行脚本,而是使用当前shell环境执行,用于 .bashrc或者.bash_profile被修改的时候,咱们没必要重启shell或者从新登陆系统,就能使当前的更改生效。服务器
咱们写一个shell脚本时,老是习惯在最前面加上一行 #!/binbash
,它就是脚本的shebang
,至于为何叫这么个奇怪的名字,C语言和Unix的开发者丹尼斯·里奇称它为多是相似于"hash-bang"的英国风描述性文字
;ssh
贴一段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是一个能实现自动和交互式任务的解释器,它也能解释常见的shell语法命令,其特点在如下几个命令:
spawn command
命令会fork一个子进程去执行command命令,而后在此子进程中执行后面的命令;
在ssh自动登录脚本中,咱们使用 spawn ssh user_name@ip_str
,fork一个子进程执行ssh登录命令;
expect命令是expect解释器的关键命令,它的通常用法为 expect "string"
,即指望获取到string字符串,可在在string字符串里使用 * 等通配符;
string与命令行返回的信息匹配后,expect会马上向下执行脚本;
set timeout n
命令将expect命令的等待超时时间设置为n秒,在n秒内尚未获取到其期待的命令,expect 为false,脚本会继续向下执行;
send命令的通常用法为 send "string"
,它们会咱们日常输入命令同样向命令行输入一条信息,固然不要忘了在string
后面添加上 \r
表示输入回车;
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
命令,一键登录成功!
简单的几个命令,,搭配起来解决了与命令行的交互问题后,不少复杂的功能也不在话下了~
脚本完成了,但是仍是有些小瑕疵:
./file_name.sh
命令太长。。。这里咱们想到了linux的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文件,此文件会在终端窗口建立的时候首先执行一次,因此能够帮咱们再设置一次别名;
执行命令vim ~./bash_profile
,在文件内部添加:
alias alias_name="/root_dir/../file_name.sh
保存后,再使用 . ~./bash_profile
或source ~./bash_profile
在当前脚本执行一遍设置别名命令,完成设置;
这样,咱们不管在哪一个目录,只要输入alias_name
命令,回车,真正的一键登录!
做为一个程序猿,时刻保持着偷懒
意识(固然此偷懒非彼偷懒。。。),在类unix系统中,不要浪费了shell
这种神奇的工具,让计算机为咱们服务~
一个多月没写博客了,最近在看APUE,UNP一套的书,C和Unix上入门尚浅,不敢乱写误人子弟;日常本身用记事本作的笔记也比较散乱,不成系统;
慢慢积累吧,有适当的项目会写的,欢迎你们关注~