Linux Day05
Day05
流程控制
for循环
- 简单for循环
for NUM in 1 2 3 ; do SUM=$[SUM+NUM] done - 序列for循环
for NUM in {1..2}; do SUM=$[SUM+NUM] done - 变量for循环
sum=0 for((i=1;i<=3;i++)) ; do let sum=sum+i done echo $sum
while循环
语法
while 表达式( ((i<=3)) / [ $i -le 3 ] ) ; do
done
示例
i=1
sum=0
while ((i<=100)) ; do
let sum=sum+i
let i++
done
until循环
条件与while相反,也就是表达式为false时才执行
语法
until 表达式
do
done
示例
sum=0
i=1
until ((i>100)); do
let sum=sum+i
let i++
done
echo $sum
数组
数组定义
arr=(num1 num2….)
获取元素
${arr[index]}
获取所有元素
${arr[*]}
${arr[@]}
获取数组的下标
${!arr[*]}
获取数组的长度
$[#arr[*]}
数组连接
arr+=(aa bb)
删除数组的元素
unset arr[index]
截取数组
${arr[*]:index:length}
```
## 遍历数组
```bash
for num in ${arr[*]};do
echo $num;
done
for num in ${!arr[*]}; do
echo ${arr[num]}
done
函数
先定义在执行;
语法
f_name(){
函数体
}
示例
hello(){
echo $1
echo $2
return 2
}
hello aa bb
echo $?
自动安装脚本
自动安装(安装jdk)
将资源放置到http服务器
[root@hdp01 ~]# mkdir /var/www/html/soft
[root@hdp01 ~]# cp jdk-8u73-linux-x64.tar.gz /var/www/html/soft/
脚本
#!/bin/bash
# 1. 从http服务器下载jdk包
wget http://192.168.2.101/soft/jdk-8u73-linux-x64.tar.gz
# 2. 加压jdk
tar zxvf jdk-8u73-linux-x64.tar.gz -C /usr/local/
# 3. 配置环境变量
cat > /etc/profile.d/java.sh << EOF
export JAVA_HOME=/usr/local/jdk1.8.0_73
export PATH=\$JAVA_HOME/bin:\$PATH
EOF
<<! # 多行注释信息
cat >> /etc/profile << EOF
export JAVA_HOME=/usr/local/jdk1.8.0_73
export PATH=\$JAVA_HOME/bin:\$PATH
EOF
!
# 4. 测试
source /etc/profile.d/java.sh
java -version
发送、自动调用
[root@hdp01 ~]# cat send.sh
#!/bin/bash
SERVICES=(hdp01 hdp02 hdp03)
for SERVICE in ${SERVICES[*]}; do
scp -r ~/autoInstall.sh root@${SERVICE}:~/
ssh $SERVICE sh autoInstall.sh
echo "${SERVICE} success..."
done
模拟人机交互
使用expect命令,需要其他命令
| 命令 | 描述 |
|---|---|
| set | 可以设置超时,也可以设置变量 |
| timeout | 超时等待时间,默认 10s |
| spawn | 执行一个命令 |
| expect | 匹配输出的内容 |
| exp_continue | 继续执行下面匹配 |
#!/bin/bash
SERVICES=(hdp02 hdp03)
for SERVICE in ${SERVICES[*]} ; do
expect -c "
spawn ssh-copy-id ${SERVICE}
expect {
\"(yes/no)?\" {send \"yes\r\";exp_continue}
\"password:\" {send \"PASSWD\r\";exp_continue}
}
"
done
日期操作
常见选项
-d: 用于日期的计算
--date="date" 用于日期的计算
日期时间显示
日期方面
%a : 星期几 (Sun..Sat)
%A : 星期几 (Sunday..Saturday)
%b : 月份 (Jan..Dec)
%B : 月份 (January..December)
%c : 直接显示日期和时间
%d : 日 (01..31)
%D : 直接显示日期 (mm/dd/yy)
%h : 同 %b
%j : 一年中的第几天 (001..366)
%m : 月份 (01..12)
%U : 一年中的第几周 (00..53) (以 Sunday 为一周的第一天的情形)
%w : 一周中的第几天 (0..6)
%W : 一年中的第几周 (00..53) (以 Monday 为一周的第一天的情形)
%x : 直接显示日期 (mm/dd/yyyy)
%y : 年份的最后两位数字 (00.99)
%Y : 完整年份 (0000..9999)
时间方面
%%: 打印出%
%n : 下一行
%t : 跳格
%H : 小时(00..23)
%k : 小时(0..23)
%l : 小时(1..12)
%M : 分钟(00..59)
%p : 显示本地AM或PM
%P : 显示本地am或pm
%r : 直接显示时间(12 小时制,格式为 hh:mm:ss [AP]M)
%s : 从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数
%S : 秒(00..61)
%T : 直接显示时间(24小时制)
%X : 相当于%H:%M:%S %p
%Z : 显示时区
日期计算
# 当前时间
[root@hdp01 ~]# date
Thu Nov 1 14:11:12 CST 2018
# 昨天
[root@hdp01 ~]# date -d last-day
Wed Oct 31 14:11:06 CST 2018
[root@hdp01 ~]# date -d "last day"
Wed Oct 31 14:11:24 CST 2018
[root@hdp01 ~]# date -d yesterday
Wed Oct 31 14:11:33 CST 2018
# 明天
[root@hdp01 ~]# date -d "next day"
Fri Nov 2 14:12:06 CST 2018
[root@hdp01 ~]# date -d next-day
Fri Nov 2 14:12:14 CST 2018
[root@hdp01 ~]# date -d tomorrow
Fri Nov 2 14:12:53 CST 2018
# 上个月
[root@hdp01 ~]# date -d last-month
Mon Oct 1 14:12:42 CST 2018
# 上周
[root@hdp01 ~]# date -d last-week
Thu Oct 25 14:13:03 CST 2018
# 去年
[root@hdp01 ~]# date -d last-year
Wed Nov 1 14:13:06 CST 2017
# 下周一
[root@hdp01 ~]# date -d "next monday"
Mon Nov 5 00:00:00 CST 2018
# 明天
[root@hdp01 ~]# date --date="next day"
Fri Nov 2 14:14:46 CST 2018
# 前天
[root@hdp01 ~]# date --date="last day"
Wed Oct 31 14:15:53 CST 2018
# 明天
[root@hdp01 ~]# date --date="1 day"
Fri Nov 2 14:15:57 CST 2018
# 昨天
[root@hdp01 ~]# date --date="-1 day"
Wed Oct 31 14:16:00 CST 2018
# 明天
[root@hdp01 ~]# date --date="-1 day ago"
Fri Nov 2 14:16:05 CST 2018
# 昨天
[root@hdp01 ~]# date --date="1 day ago"
Wed Oct 31 14:16:11 CST 2018
# 一月后
[root@hdp01 ~]# date --date="1 month"
Sat Dec 1 14:17:03 CST 2018
# 一月零三天后
[root@hdp01 ~]# date --date="1 month 3 day"
Tue Dec 4 14:17:18 CST 2018
[root@hdp01 ~]#
# 注意:
# 指定日期运算
date -d "may 14 -2 week"
日期字符串计算
+%s 将字符串转换为秒级时间,然后进行计算
date +%s -d "datestr"
文本处理
wc(WordCound)
常见选项
-l:统计行数
-w:统计单词数
-c:统计字节数
-m:统计字符数
-L:统计最长行或者字符串长度
示例
# 统计文件信息
[linux@linux ~]$ wc wc.txt
4 8 77 mingxing.txt
行数 单词数 字节数 文件名
# 统计字符串长度
[linux@linux ~]$ echo "hello" | wc -L
sort(排序)
常见选项
-g:按照数值排序
-n:代表按照字符串数值排序
-t:指定分隔符
-k:pos1,pos2 比较的开始和结束为止
-r:倒序排序
-u:去重
示例
# 以:作为分隔符,取第二个字段按照数值进行排序
[linux@linux ~]$ sort -nk 2 -t : sort.txt
aaa:10:1.1
ccc:20:3.3
fff:30:2.2
ddd:30:3.3
bbb:40:4.4
bbb:40:4.4
eee:40:5.5
# 和上一个不一样的是-u为了去重
[linux@linux ~]$ sort -nk 2 -u -t : sort.txt
aaa:10:1.1
ccc:20:3.3
ddd:30:3.3
bbb:40:4.4
# 多列排序:以:分隔,按第二列数值排倒序,第三列正序
[linux@linux ~]$ sort -n -t: -k2,2r -k3 sort.txt
bbb:40:4.4
bbb:40:4.4
eee:40:5.5
fff:30:2.2
ddd:30:3.3
ccc:20:3.3
aaa:10:1.1
uniq(去重,必须相邻)
可以先排序,在去重
常见参数
-d:打印重复行
-u:打印不重复
示例
# 求两个文件的交集:
[hadoop@hadoop04 data]$ cat a.txt b.txt | sort | uniq -d
# 求两个文件的并集:
[hadoop@hadoop04 data]$ cat a.txt b.txt | sort | uniq
# 求a.txt和b.txt的差集
[hadoop@hadoop04 data]$ cat a.txt b.txt b.txt | sort | uniq -u
# 求b.txt和a.txt的差集
[hadoop@hadoop04 data]$ cat b.txt a.txt a.txt | sort | uniq -u
cut(提取文本和流)
常见参数
-d:指定分隔符
-f:获取第几列
示例
# 将PATH变量取出,找出第五个路径
[root@localhost ~]# echo $PATH | cut -d ':' -f 5
/usr/sbin
# 将PATH变量取出,找出第三和第五个路径,以下三种方式都OK
[root@localhost ~]# echo $PATH | cut -d ':' -f 3,5
[root@localhost ~]# echo $PATH | cut -d : -f 3,5
[root@localhost ~]# echo $PATH | cut -d: -f3,5
/sbin:/usr/sbin
# 将PATH变量取出,找出第一到第三,还有第五个路径
[root@localhost ~]# echo $PATH | cut -d ':' -f 1-3,5
/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin
grep(文本生成器)
常见参数
-c:统计行数
-i:忽略大小写
-v:条件取反
基本使用
# 搜索文件(打印行)
grep hdp01 /etc/passwd
grep aa ./*.txt
# 流中搜索
cat /etc/passwd | grep hdp01
选项使用
# 统计行数
grep -c is grep.txt
# 反向提取
grep -v is grep.txt
正则表达式
最好使用egrep命令,这样正则表达式的写法就和java等其他语言一样,不需要转义;
sed
sed是一种在线编辑器,它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间",接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。
常见的选项和动作
-n:输出修改行
-e:多点编辑
a:追加
i:插入
d:删除
p:打印
c:行替换
s:字符串替换 行范围/s/str1/str2/g
# s@@@1修饰符 1表示替换第一个;如果修改时符是g,则表示所有;
示例
## 删除 d命令
# 删除sed.txt文件的第二行。
sed '2d' sed.txt
# 删除sed.txt文件的第二行到末尾所有行。
sed '2,$d' sed.txt
# 删除sed.txt文件的最后一行。
sed '$d' sed.txt
# 删除sed.txt文件所有包含test的行。
sed '/test/d ' sed.txt
# 删除sed.txt文件所有包含字母的行。
sed '/[A-Za-z]/d ' sed.txt
## 整行替换:c命令
# 将第二行替换成hello world
sed '2c hello world' sed.txt
## 字符串替换:s命令
# 在整行范围内把hello替换为hi。如果没有g标记,则只有每行第一个匹配的hello被替换成hi。
sed 's/hello/hi/g' sed.txt
# 此种写法表示只替换每行的第2个hello为hi
sed 's/hello/hi/2' sed.txt
# 此种写法表示只替换每行的第2个以后的hello为hi(包括第2个)
sed 's/hello/hi/2g' sed.txt
## &符号表示后项引用匹配到的整个字符串。所有以192.168.0.1开头的行都会被替换成它自已加 -localhost,变成192.168.0.1-localhost。第三句表示给IP地址添加中括号
sed -n 's/hello/&-hi/gp' sed.txt
sed 's/^192.168.0.1/&-localhost/' sed.txt
sed 's/^192.168.0.1/[&]/' sed.txt
## 编号后项引用
## liu被标记为\1,所以liu会被保留下来(\1 == liu)
## ling被标记为\2,所以ling也会被保留下来(\2 == ling)
## 所以最后的结果就是\1tao\2ss == "liu" + "tao" + "ling" + "ss"
sed -n 's/\(liu\)jialing/\1tao/p' sed.txt
sed -n 's/\(liu\)jia\(ling\)/\1tao\2ss/p' sed.txt
## 多点编辑:e命令
sed -e '1,5d' -e 's/hello/hi/' sed.txt
## 写入文件:w命令
sed -n '/hello/w file' sed.txt
## 从文件读入:r命令
sed '/hello/r file' sed.txt
## 追加命令:a命令
# '--->this is a example'被追加到以hello开头的行(另起一行)后面,sed要求命令a后面有一个反斜杠。
sed '/^hello/a\\--->this is a example' sed.txt
## 插入:i命令
# 如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。
sed '/will/i\\some thing new ------------' sed.txt
##下一个:n命令
# 如果hello被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。
sed '/hello/{n; s/aa/bb/;}' sed.txt 替换下一行的第一个aa
sed '/hello/{n; s/aa/bb/g;}' sed.txt 替换下一行的全部aa
## 退出:q命令
# 打印完第10行后,退出sed。
sed '10q' sed.txt
awk(报表生成器)
awk就是扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。但是语法非常复杂,可以看成一门编程语言了;
常见参数
-F:指定分割符
{print $n(1-)}:打印指定列
BEGIN/END(只执行一次)
# 变量
NF:number of field,字段数量
NR:number of record,行数
示例
# 打印 第一列
awk -F: '{print $1}' /etc/passwd
# 先打印 begin,然后打印第七列,最后打印 end
awk -F: 'BEGIN{print "name,shell"} {print $1","$7} END{print "haha,heihei"}' /etc/passwd
# 使用字符串替换,打印第一列和最后一列
awk -F: '{printf("name=%s,shell=%s",$1,$NF)}' /etc/passwd
awk -F: '{printf("%s,%s\n",$1,$NF)}' /etc/passwd
find
find 路径 选项 表达式
常用选项
# 选项
-name "PATTERN"
-type TYPE:
f:普通文件
d:目录文件
l:符号链接文件
b:块设备文件
c:字符设备文件
p:管道文件
s:套接字文件
-user USERNAME:查找属主为指定用户的所有文件;
-group GROUPNAME:查找属组为指定组的所有文件;
-uid UID:查找属主为指定UID的所有文件;
-gid GID:查找属组为指定GID的所有文件;
-nouser :查找没有属主的文件;
-nogroup:查找没有属组的文件;
# 组合测试:
与:-a,默认组合逻辑;添加在两个条件之间;
或:-o,添加在两个条件之间;
非:-not,!;在整个测试条件之前添加参数;
字符串操作
常用语法
${#var}:获取长度
## 基于模式取子串
${var#*word}:其中word是指定的分隔符;功能;自左而右,查找var变量所存储的字符串中,第一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符;
${var##*word}:其中word是指定的分隔符;功能;自左而右,查找var变量所存储的字符串中,最后第一次出现的word分隔符,删除字符串开头至此分隔符之间的所有字符;
${var%word*}:其中word是指定的分隔符;功能;自右而左,查找var变量所存储的字符串中,第一次出现的word分隔符,删除此分隔符至字符串尾部之间的所有字符;
${var%%word*}:其中word是指定的分隔符;功能;自右而左,查找var变量所存储的字符串中,最后第一次出现的word分隔符,删除此分隔符至字符串尾部之间的所有字符;
## 查找替换
${var/PATTERN/SUBSTI}:查找var所表示的字符串中,第一次被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;
${var//PATTERN/SUBSTI}:查找var所表示的字符串中,所有被PATTERN所匹配到的字符串,并将其全部替换为SUBSTI所表示的字符串;
${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;
${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;
## 查找删除
${var/PATTERN}:以PATTERN为模式查找var字符串中第一次的匹配,并删除之;
${var//PATTERN}
${var/#PATTERN}
${var/%PATTERN}
示例
WEBSITE='http://hadoop//centos/huangbo.html'
[root@hadoop ~]# echo ${WEBSITE#*//}
hadoop//centos/huangbo.html
[root@hadoop ~]# echo ${WEBSITE##*//}
centos/huangbo.html
[root@hadoop ~]# echo ${WEBSITE%//*}
http://hadoop
[root@hadoop ~]# echo ${WEBSITE%%//*}
http:
使用shell脚本自动安装MySQL
前提
将所有mysql的安装包,放置到http的服务器上
安装脚本 一次性
[root@hdp02 ~]# cat imysql.sh
#!/bin/bash
## auto install mysql
## 假如是第二次装,那么要先停掉服务,并且卸载之前的mysql
service mysql stop
## 卸载所有已经存在的MySQL
EXISTS_RPMS=`rpm -qa | grep -i mysql`
## 查看已经存在的MySQL安装包
echo ${EXISTS_RPMS}
for RPM in ${EXISTS_RPMS} ; do
rpm -e --nodeps ${RPM}
done
## 删除残留文件
rm -fr /usr/lib/mysql
rm -fr /usr/include/mysql
rm -f /etc/my.cnf
rm -fr /var/lib/mysql
## 从服务器获取安装mysql的rpm包
wget http://192.168.2.101/soft/MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm
wget http://192.168.2.101/soft/MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 删除之前的密码文件,以免产生干扰
rm -rf .mysql_secret
## 安装服务器
rpm -ivh MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 安装客户端
rpm -ivh MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 然后删除刚刚下下来的rpm包
rm -rf MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm
rm -rf MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 提示安装的步骤都完成了。
echo "install mysql server and client is done .!!!!!!"
## 打印出来刚刚生成的mysql初始密码
echo "random password is:${PSWD}"
## 开启mysql服务
service mysql start
## 输入新密码
NPWD=root
## 获取到生成的随机密码
PWD=`awk -F" " '{print $NF}' .mysql_secret`
## 重建yum缓存
#yum makecache
## 安装expect
#yum install -y expect
## 修改密码
expect -c "
set timeout 10
spawn mysql_secure_installation
expect \"Enter current password for root (enter for none):\"
send \"$PWD\r\"
expect \"Change the root password?\"
send \"y\r\"
expect \"New password: \"
send \"$NPWD\r\"
expect \"Re-enter new password: \"
send \"$NPWD\r\"
expect \"Remove anonymous users?\"
send \"y\r\"
expect \"Disallow root login remotely?\"
send \"y\r\"
expect \"Remove test database and access to it?\"
send \"y\r\"
expect \"Reload privilege tables now?\"
send \"y\r\"
expect eof
"
echo "密码修改完成"
## 授权
mysql -uroot -p${NPWD} << EOF
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY "${NPWD}" WITH GRANT OPTION;
FLUSH PRIVILEGES;
use mysql;
select host, user, password from user;
EOF
echo "授权完成"
多次版本
安装脚本
#!/bin/bash
## auto install mysql
## 假如是第二次装,那么要先停掉服务,并且卸载之前的mysql
service mysql stop
EXISTS_RPMS=`rpm -qa | grep -i mysql`
echo ${EXISTS_RPMS}
for RPM in ${EXISTS_RPMS}
do
rpm -e --nodeps ${RPM}
done
## 删除残留文件
rm -fr /usr/lib/mysql
rm -fr /usr/include/mysql
rm -f /etc/my.cnf
rm -fr /var/lib/mysql
## 从服务器获取安装mysql的rpm包
wget http://linux/soft/MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm
wget http://linux/soft/MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 删除之前的密码文件,以免产生干扰
rm -rf /root/.mysql_secret
## 安装服务器
rpm -ivh MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 获取到生成的随机密码
##PSWD=`cat /root/.mysql_secret | awk -F ':' '{print substr($4,2,16)}'`
PSWD=` grep -v '^$' /root/.mysql_secret | awk -F ':' '{print substr($4,2,16)}'`
##PSWD=${PWD:1:16}
## 安装客户端
rpm -ivh MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 然后删除刚刚下下来的rpm包
rm -rf MySQL-client-5.6.26-1.linux_glibc2.5.x86_64.rpm
rm -rf MySQL-server-5.6.26-1.linux_glibc2.5.x86_64.rpm
## 提示安装的步骤都完成了。
echo "install mysql server and client is done .!!!!!!"
## 打印出来刚刚生成的mysql初始密码
echo "random password is:${PSWD}"
## 开启mysql服务
service mysql start
手动第一次登陆,并修改密码
[root@hadoop bin]# mysql -uroot -pZjVIWvOGD18bT7oX
mysql> set PASSWORD=PASSWORD('root');
授权
[root@hadoop bin]# vi initMysql.sh
#!/bin/bash
mysql -uroot -proot << EOF
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
use mysql;
select host, user, password from user;
EOF


浙公网安备 33010602011771号