shell-远程连接

何时需要远程连接

远程连接嘛,自然是本机访问不了了。这种情况还是比较常见的,比如服务器上的数据库,远端的主机等情况。

如果仅仅只是连接一次啥的,那就没必要下面的那些东西,因为手动输入反而简单一些。

连接方式

数据库

需要脚本的一个原因是要可以重复执行,另一个原因是连接上去之后的步骤比较多。如果是使用数据库的话,Oracle,mysql,mariadb等都可以直接写语句,语句间用分号隔开,它便会一个语句一个语句的执行,所以不需要担心啥

1
2
3
4
5
mariadb -h192.168.0.102 -upi -p123456 -Dmytestdb <<EOF | sed -n '2p' |xargs -n1|sed -n '2,12p'
show tables;
select count(1) from ssacount;
select * from ssacount limit 1,5;
EOF

可以将查询出来的数据进行过滤,这样就会直接显示出来,如果写的是个脚本,其实啥也得不到,所以得把输出存入变量。

1
2
3
4
5
data=`mariadb -h192.168.0.102 -upi -p123456 -Dmytestdb <<EOF | sed -n '2p' |xargs -n1|sed -n '2,12p'
show tables;
select count(1) from ssacount;
select * from ssacount limit 1,5;
EOF`

这样便把数据存入了变量data中,数据库操作还是比较简单的。

ssh连接

这个就稍微复杂点了,因为它不像数据库那样,可以一次执行许多语句。而且最后得到数据也是比较麻烦,虽然我电脑上可以使用重定向来得到,但是公司的怎么写都不行,可能版本不同吧。为了连接主机后执行许多步骤那就得使用一个工具了:expect

expect是一个工具套装,有它自己的语法,所以不能把它简简单单的看做只是一个shell命令。有的电脑上可能还没有这个东西,比如我的电脑。所以首先要安装它

1
sudo pacman -S expect

有了它就和使用sqlplus以及mariadb等的连接方式一样了,因为借助expect,可以执行许多命令。

网上看到许多教程,里面写的都是直接使用expect来为脚本解释的。例如

1
2
#!/usr/bin/expect
#然后写其他的巴拉巴拉

这么写,我总觉得不是很好,除非我们就仅仅去连一下主机,然后也无法使用shell命令来操作得到的数据,因为它根本不是使用的shell来解释的,也可以理解为这不是一个shell脚本吧。除非我们再写一个shell脚本,在脚本中调用这个expect脚本。这样不是多此一举吗?所以来个大杂烩吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
#这里我们仍然指定shell脚本,使用bash来解释

#这里调用工具套件expect,前面说了它有自己的语法,所以记住就行了
/usr/bin/expect <<EOF
#设置连接超时
set time 30
#spawn新开一个进程,-q表示quiet模式,会减少不必要的错误提示信息
spawn ssh -q pi@192.168.0.102
#expect捕获出现的数据
expect {
"*yes/no*" {send "yes\r";exp_continue}
"*password*" {send "123456\r"}
}
#这里就是捕获提示符,要看具体的环境了,大多数是~提示符吧。
expect "*@"
#使用send来发送指令,\r来表示回车
send "cd /home/pi\r"
expect "*@"
send "ls \r"
#将所有的显示的数据保存为一个log文件
log_file mylogfile.txt
expect "*@"
#退出连接
send "exit\r"
#捕获结束
expect eof
EOF

如果是我的这个电脑的话是支持重定向的,就可以不用写log文件了,其实一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

/usr/bin/expect <<EOF >logfile.txt
set time 30
spawn ssh -q pi@192.168.0.102
expect {
"*yes/no*" {send "yes\r";exp_continue}
"*password*" {send "123456\r"}
}
expect "*@"
send "cd /home/pi\r"
expect "*@"
send "ls \r"
expect "*@"
send "exit\r"
expect eof
EOF

然后就可以在本地对保存的文件进行数据提取和过滤了。