技术流ken

运维拯救世界

1904课堂记录:shell编程2

shell编程

练习题:
练习1:使用root用户帐号创建并执行test2.sh,实现创建一个shelltest用户,
并在其家目录中新建文件try.html。

#!/bin/bash
useradd shelltest
touch /home/shelltest/try.html

练习2:统计当前系统总共有多少用户

#!/bin/bash
cat /etc/passwd | wc -l

练习3:统计当前已经安装的软件数量

#!/bin/bash
rpm -qa | wc -l

shell编程常用命令详解

1.grep

行处理

文本处理三剑客:grep,sed,awk

常用选项:
-i 忽略大小写
-o 只显示匹配到的内容
-v 取反
-c 打印匹配到的行数
-n 显示匹配到的字符串所在的行数
-B 匹配字符串前面的几行内容
-A 匹配字符串后面的几行内容
-C 匹配字符串前后的几行内容
-e 匹配多个字符串

例子1:匹配全文的root不区分大小写
[root@ken2 ~]# grep -i “root” test #只要是root都会变红色,不区分大小写
root:x:0:0:root:/root:/bin/bash
ROOTlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdowROOTn:x:6:0:shutdown:/sbin:/sbin/shutdown
operator:x:11:0:operator:/root:/sbin/nologin

[root@ken2 ~]# grep “root” test #只有小写的root会变红色,区分大小写
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@ken2 ~]# grep “ROOT” test #只有大写的root会变红色,区分大小写
ROOTlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
shutdowROOTn:x:6:0:shutdown:/sbin:/sbin/shutdown

例子2:统计root出现的行的数量
[root@ken2 ~]# grep -ic “root” test
4

例子3:只显示指定的字符串
[root@ken2 ~]# grep -io “root” test
root
root
root
ROOT
ROOT
root

例子4:统计匹配到的内容出现的次数
[root@ken2 ~]# grep -io “root” test | wc -l
6

例子5:找到不包含root的行
[root@ken2 ~]# grep -vi “root” test
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

例子6:统计文本里面的空行数量
方法一:
[root@ken2 ~]# grep “^$” test | wc -l
2

方法二:
[root@ken2 ~]# grep -c “^$” test
2

例子7:去除文本中的空行
[root@ken2 ~]# cp test test.bak #首先备份原文件
[root@ken2 ~]# grep -v “^$” test.bak > test #在备份文件中进行过滤操作并导入到原文件中
[root@ken2 ~]# cat test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
ROOTlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdowROOTn:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

例子8:匹配root下面的2行内容
[root@ken2 ~]# grep -A 2 “root” test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

operator:x:11:0:operator:/root:/sbin/nologin

例子9:显示匹配到的内容的前后几行内容
[root@ken2 ~]# grep -C 2 “lp” test
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

例子10.显示匹配到的内容的后几行B
[root@ken2 ~]# grep -B 2 “root” test
root:x:0:0:root:/root:/bin/bash

halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

例子11:显示root所在行号
[root@ken2 ~]# grep -n “root” test
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

crond是周期性计划任务的服务,命令行工具crontab,crond已经默认开机自启!
atd是一次性计划任务的服务,命令行工具是at,自行下载启动!

2. cut
选项:
-c 指定截取的字符串
-d 指定分隔符
-f 指定分隔符后显示的列数

例子1:获取6位随机密码
[root@ken2 ~]# echo $RANDOM | md5sum | cut -c 1-8

例子2:只显示/etc/passwd里面的所有用户
[root@ken2 ~]# cut -d “:” -f 1 /etc/passwd

例子3:只显示/etc/passwd里面的所有用户的shell类型
[root@ken2 ~]# cut -d “:” -f 7 /etc/passwd

3.sort命令

常用选项:
-n 按照数字进行排序 #默认是按照字符串排序
-r 降序 #默认升序

例子1:按照数字排序
[root@ken2 ~]# sort test1 #默认是按照字符串排序
1
23
4
[root@ken2 ~]# sort -n test1
1
4
23

例子2:降序排序
[root@ken2 ~]# sort -n -r test1
23
4
1

4. uniq

选项:
-c 统计行数

例子1:统计文本行数
[root@ken2 ~]# uniq -c test1
9 1
10 23
8 4
[root@ken2 ~]# uniq -c test1 | sort -rn
10 23
9 1
8 4

例子2:统计相同的行数出现的次数
[root@ken2 ~]# sort test1 | uniq -c | sort -rn

5. seq

例子1
[root@ken2 ~]# seq 6 #一个数字表示终止位,从1开始
1
2
3
4
5
6
[root@ken2 ~]# seq 2 6 #两个数字第一个表示起始位,第二个表示终止位
2
3
4
5
6
[root@ken2 ~]# seq 2 2 10 #三个数字第一个表示起始位,第二个表示步长,第三个表示终止位
2
4
6
8
10

例子2:生成100以内的奇数
[root@ken2 ~]# seq 1 2 100

例子3:生成100以内的偶数
[root@ken2 ~]# seq 2 2 100

6.tr

选项:
-d 删除指定的字符串

例子1:把所有的小写替换为大写
[root@ken2 ~]# echo “this is ken” | tr a-z A-Z

例子2:删除空格
[root@ken2 ~]# echo “this is ken” | tr -d ” ”
thisisken

取出来IP地址:
[root@ken2 ~]# ip a | grep “global” | cut -d “/” -f 1 | cut -d “t” -f 2 | tr -d ” ”
192.168.163.6

变量

1.定义变量

name=ken
name=’ken’
name=”ken”

name是变量名
ken是变量值

1.如果变量值没有空格的话不加双引号或者单引号是可以的,
但是有空格的话必须加上单引号或者双引号

2.如果变量值里面有变量如果加上单引号的话就是不会解释变量,所见即所得
双引号解释变量

2. 使用变量

$变量名
[root@ken2 ~]# name=ken
[root@ken2 ~]# echo $name
ken

规范引用变量需要加上花括号:
[root@ken2 ~]# echo ${name}
ken

必须加花括号的情况:
[root@ken2 ~]# echo “this is ${name}s book”
this is kens book

3. 修改变量值

即重新赋值!
[root@ken2 ~]# echo ${name}
ken
[root@ken2 ~]# name=kitty
[root@ken2 ~]# echo ${name}
kitty

4.删除变量
unset
[root@ken2 ~]# echo ${name}
kitty
[root@ken2 ~]# unset name
[root@ken2 ~]# echo ${name}

5.把命令的执行结果赋值给变量

方法一:
[root@ken2 ~]# name=`ls -l`
[root@ken2 ~]# echo $name
total 24 -rw-r–r– 1 root root 385 Jul 9 17:58 test -rw-r–r– 1 root root 91 Jul 9 18:41 test1 -rw-r–r– 1 root root 61 Jul 9 17:35 test1.sh -rw-r–r– 1 root root 36 Jul 9 17:36 test2.sh -rw-r–r– 1 root root 28 Jul 9 17:37 test3.sh -rw-r–r– 1 root root 395 Jul 9 17:54 test.bak

方法二:
[root@ken2 ~]# name1=$(ls -l)
[root@ken2 ~]# echo $name1
total 24 -rw-r–r– 1 root root 385 Jul 9 17:58 test -rw-r–r– 1 root root 91 Jul 9 18:41 test1 -rw-r–r– 1 root root 61 Jul 9 17:35 test1.sh -rw-r–r– 1 root root 36 Jul 9 17:36 test2.sh -rw-r–r– 1 root root 28 Jul 9 17:37 test3.sh -rw-r–r– 1 root root 395 Jul 9 17:54 test.bak

6.变量类型

局部变量 只在当前shell中有效,另开shell无效
环境变量 即全局变量。在所有shell中都有效,
[root@ken2 ~]# tail -1 /etc/profile
export name=ken
[root@ken2 ~]# source /etc/profile

shell变量 即$0,$1,$# $* $?
[root@ken2 ~]# cat test1.sh
#!/bin/bash
echo “脚本名:$0”
echo “第一个参数:$1”
echo “第二个参数:$2”
echo “参数个数:$#”
echo “所有的参数:$*”

所有的参数:
[root@ken2 ~]# bash test1.sh ken 18
脚本名:test1.sh
第一个参数:ken
第二个参数:18
参数个数:2
所有的参数:ken 18

7. 退出状态
$?
打印$0如果现实非0都是错误状态,即命令没有执行成功!
[root@ken2 ~]# echo $?
0
[root@ken2 ~]# ken
-bash: ken: command not found
[root@ken2 ~]# echo $?
127
[root@ken2 ~]# systemctl restart jkj
Failed to restart jkj.service: Unit not found.
[root@ken2 ~]# echo $?
5

8.整数比较符

-eq equal 等于
-le lesser equal 小于等于
-ge greater equal 大于等于
-lt lesser then 小于
-gt greater then 大于
-ne not equal 不等于

9.条件表达式
[]
[root@ken2 ~]# [ 1 -eq 1 ] && echo “1” || echo “2”
1
[root@ken2 ~]# [ 1 -eq 2 ] && echo “1” || echo “2”
2
[root@ken2 ~]# [ 1 -eq 2 ] && echo “1” || echo “2” && echo “3”
2
3
[root@ken2 ~]# [ 1 -eq 2 ] && echo “1” || echo “2” && echo “3” || echo “4” && echo “5”
2
3
5

10.字符串比较

判断字符串的时候一定要加双引号!!!!!

== 判断字符串是否相等 相等为真
!= 判断字符串是否不相等 不相等为真
-n 字符串不为空才为真
-z 字符串为空才为真

例子1:

[root@ken2 ~]# [ “ken” == “$name” ] && echo “1” || echo “2”
1
[root@ken2 ~]# [ “kenken” == “$name” ] && echo “1” || echo “2”
2
[root@ken2 ~]# [ “kenken” != “$name” ] && echo “1” || echo “2”
1
[root@ken2 ~]# [ “ken” != “$name” ] && echo “1” || echo “2”
2

例子2:
[root@ken2 ~]# [ -z “$name” ] && echo “1” || echo “2”
2
[root@ken2 ~]# [ -n “$name” ] && echo “1” || echo “2”
1

11.文件测试
-e 判读文件是否存在
-f 判断文件 是普通文件必须存在
-d 判断目录 是目录必须存在

例子1:
[root@ken2 ~]# [ -e /etc/passwd ] && echo “1” || echo “2”
1
[root@ken2 ~]# [ -e /etc/pasdadswd ] && echo “1” || echo “2”
2

12. 布尔运算符
-a 和
真 真 真
真 假 假
假 真 假
假 假 假

-o 或
真 真 真
真 假 真
假 真 真
假 假 假

! 取反
真 假
假 真

例子1:
[root@ken2 ~]# [ -d /etc -a 1 -lt 1 ] && echo “1” || echo “2”
2

例子2:
[root@ken2 ~]# [ -d /etc -o 1 -lt 1 ] && echo “1” || echo “2”
1
[root@ken2 ~]# [ -d /etc/passwd -o 1 -lt 1 ] && echo “1” || echo “2”
2

例子3:

[root@ken2 ~]# [ ! -d /etc/passwd ] && [ 1 -eq 1 ] && echo “1” || echo “2”
1

13. 整数运算

let
[root@ken2 ~]# num=1
[root@ken2 ~]# let num++
[root@ken2 ~]# echo $num
2
[root@ken2 ~]# let num++
[root@ken2 ~]# echo $num
3

[root@ken2 ~]# let num+=1
[root@ken2 ~]# echo $num
4
[root@ken2 ~]# let num=num+1
[root@ken2 ~]# echo $num
5

三者相同!
let num++
let num+=1
let num=num+1

[root@ken2 ~]# num=$((num+5))
[root@ken2 ~]# echo $num
17
[root@ken2 ~]# num=$((num+1))
[root@ken2 ~]# echo $num
18
[root@ken2 ~]# num=$((num+3))
[root@ken2 ~]# echo $num
21

发表评论

电子邮件地址不会被公开。