- expect实现无交互登录
#!/usr/bin/expect定义脚本执行的shell
set timeout 30 设置超时时间,单位秒, timeout -1 永不超时
spawn expect内部命令,给ssh进程加壳,用来传递交互指令。(启动新的进程)
expect expect 内部命令,判断输出结果是否包含某项字符串,没有则立即返回,继续向下执行,有就等待一段时间返回,等待时间由timeout设置(从进程接收字符串)
send 执行交互动作,将交互要执行的动作进行输入给交互指令,命令结尾字符串要加上\r,如果出现异常等待的状态可以进行核查。(向进程发送字符串)
exp_continue 继续执行接下来的交互动作
interact 执行完成后保持交互状态,把控制权交给控制台;(允许用户交互)
$argv expect脚本可以接收从bash传递来的参数,可用[lindex $argv n ]获得,n从0开始,分别表示第一个,第二个,第三个...参数,
例1:免密码登通过ssh服务器,非密钥
vim ssh.exp
#!/usr/bin/expect
#timeout默认为10,expect空格{
set ip "192.168.0.60"
set name "root"
set passwd "123456"
set timeout 30
spawn ssh $name@$ip
expect {
"yes/no" {send "yes\r";exp_continue}
"password" {send "$passwd\r";}
}
expect "#"
send "touch /root/expect.txt\r"
send "ls /etc/ > /root/expect.txt\r"
send "exit\r"
expect eof
例2:对服务器批量管理
vim ip_pass.txt
192.168.0.60 123456
192.168.0.60 123456
192.168.0.60 123456
vim ssh2.exp
#!/usr/bin/expect
set ip [lindex $argv 0]
set passwd [lindex $argv 1]
set timeout 30
spawn ssh root@$ip
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "$passwd\r" }
}
expect "#"
send "touch /root/expect.txt\r"
send "ls /etc/ > /root/expect.txt\r"
send "exit\r"
expect eof
vim login.sh
#!/bin/bash
for ip in `awk '{print $1}' /root/ip_pass.txt`
do
pass=`grep $ip /root/ip_pass.txt|awk '{print $2}'`
expect /root/ssh2.exp $ip $pass
done
- 正则表达式
不同工具用不同正则,如grep,sed,awk
linux中常用的两种正则引擎,基础正则BRE,扩展正则BRE
基础正则如下表:
$ |
匹配输入字符串的结尾位置。 |
() |
标记一个子表达式的开始和结束位置。 |
* |
匹配前面的字符0次1次或多次。 |
+ |
匹配前面的字符至少1次或多次。 |
? |
匹配前面的字符0次或1次。 |
. |
匹配任意单个字符。 |
[ |
标记一个中括号表达式的开始。 |
\ |
转义符 |
^ |
匹配输入字符串的开始位置。 |
$ |
匹配输入字符串结尾的位置。 |
{ |
标记限定符号表达式的开始。 |
| |
指明两项之间的一个选择。 |
\n |
匹配一个换行符 |
\r |
匹配一个回车符 |
\t |
匹配一个制表符 |
[] |
匹配范围内的任意单个字符 |
[^] |
匹配范围外的任意单个字符,[:digit:] 、[:lower:]、[:upper:]、[:alpha:]、[:alnum:]、[:punct:]、[:space:]
|
{m} |
匹配前面的字符m次 |
{m,n} |
匹配前面的字符至少m次,至多n次 |
- sed流编辑器
sed的执行过程:
- 一次读取一行数据
- 根据规则匹配相关数据
- 按照命令修改数据流中的数据,比如替换
- 将结果进行输出
- 重复上面4步
语法格式:sed [options] 'commands' filename
选项:
-a |
在当前行下面插入文件 |
-n |
读取下一个输入行,用下一个命令处理新的行而不是用第一个命令(取消默认输出) |
-e |
执行多个sed指令 |
-f |
运行脚本 |
-i |
编辑文件内容 *** |
-i.bak |
编辑的同时创造.bak的备份 |
-r |
使用扩展的正则表达式 |
命令:
i |
在当前行上面插入文件 |
c |
把选定的行改为新的指定的文本 |
p |
打印 *** |
d |
删除 *** |
r/R |
读取文件/一行 |
w |
另存 |
s |
查找 |
y |
替换 |
h |
拷贝模板快的内容到内存中的缓冲区 |
H |
追加模板快的内容到内存中的缓冲区 |
g |
获得内存缓冲区的内容,并替代当前模板快中的文本 |
G |
获得内存缓冲区的内容,并追加到当前模板快文本的后面 |
D |
删除\n之前的内容 |
P |
打印\n之前的内容 |
替换标记:
数字:表示新文本将替换第几行模式匹配的地方
g:表示新文本将会替换所有匹配的文本
\1:串匹配标记,前面搜索可以用元字符集\(..\),
&:保留搜索到的字符用来替换其它字符
sed匹配字符集
/^sed/匹配所有sed开头的行
/sed$/匹配所有sed结尾的行
/s.d/匹配s后接一个的任意字符,最后是d
/[[:space:]]*sed/匹配所有模板是0个或多个空格后紧跟sed的行
例1:s只替换所有行中第一个匹配到的root替换为hello
sed 's/root/hello/ /etc/passwd
例2:全面替换标记g ,所有行中所有root均替换为hello
sed 's/root/hello/g' /etc/passwd
例3:单行替换,将第2行bin替换为hello
sed '2s/bin/hello
例4:多行替换,将第3行到末行中bin替换为hello
sed '3,$s/bin/hello
例 5:删除第2行到第4行内容
sed '2,4d' /etc/hosts
例 6:将包括192.168的行删除
sed '/192.168/d' /etc/hosts
例 7:当前行前面插入行
echo "hello world"|sed 'i\hello'
例8 :当前行后面插入行
echo "hello world"|sed 'a\hello'
例9:在文件末行追加内容
sed '$a\192.168.0.60 mylinux.com' /etc/hosts
例10:在文件第2行追加内容
sed '2a\192.168.0.60 mylinux.com' /etc/hosts
例11:在文件第2行到第5行追加内容(包含3,4行)
sed '2,5a\winner' a.txt
例12:将第4行内容改为hello world
sed '4c\hello world' /etc/hosts
例13:将第2行到末行全部改成hello world,(文件就只有2行了。第二行是hello world)
sed '2,$c\hello world' /etc/hosts
例14:将包括sed行的内容修改成hello(无论行内容有多长包含了sed,该行就变成hello)
sed '/sed/c\hello a.txt
例15:打印输出文件第2到第4行的内容
sed -n '2,4p' a.txt
例16:将passwd中包括root字符的行保存到a.txt
sed -n '/root/w a.txt' /etc/passwd
例17:-i对原文件进行修改保存
sed -i ''s/root/hello/' /opt/passwd
- cut常用参数
cut命令用来显示行中的指定部分,删除文件中指定字段.
功能1用来显示文件的内容,一次读取由参数file所指明的文件,将他们的内容输出到标准输出上,功能2连接两个或多个文件,如cut fl f2 > f3 把文件fl和fn的内容合并到f3文件中.
语法:cut options 参数
选项
-b :仅显示行中指定范围的字节数;
-c:仅显示行中指定范围的字符;
-d:指定字段的分隔符,默认的字段分隔符为"TAB";
-f:显示指定字段的内容;
例1:输出系统中所有用户名
cut -f1 -d":" /etc/passwd
例2:可以将一串字符作为列来显示
n- 从n到尾
n-m 从n到m
-m 从首到m
cut -c5- /etc/passwd #打印从第5个字符到尾
cut -c1-3 /etc/passwd #打印从第1个到第3个字符
cut -c-2 /etc/passwd #打印前2个字符
- 实战bash脚本语法检查和查看详细的执行过程
bash -v test.sh #查看bash是否存在语法错误
bash -x test.sh #查看bash详细执行过程