第1章 shell中的特殊变量

1.1 $

$# 表示参数的个数

1.1.1 【示例】脚本内容

  1. [root@znix ~]# cat /server/scripts/show2.sh
  2. #!/bin/bash
  3. echo 112 $#
  4. if [ $? == 0 ];then
  5. echo "OK"
  6. fi

实例1-1 执行的不同结果

  1. [root@znix ~]# sh /server/scripts/show2.sh 1 2 3 4 6
  2. 1 2 5
  3. [root@znix ~]# sh /server/scripts/show2.sh aa bb
  4. aa bb 2
  5. [root@znix ~]# sh /server/scripts/show2.sh aa bb cc
  6. aa bb 3

1.2 $?

$?表示:上一个命令执行后的状态
状态为0 表示执行正确
状态非0 表示执行错误

1.2.1 【示例】$?的使用

  1. [root@znix ~]# aaa
  2. -bash: aaa: command not found
  3. [root@znix ~]# echo $?
  4. 127
  5. [root@znix ~]# sed
  6. Usage: sed [OPTION]...
  7. [root@znix ~]# echo $?
  8. 4
  9. [root@znix ~]# sh /server/scripts/show2.sh aa bb
  10. aa bb 2
  11. [root@znix ~]# echo $?
  12. 0

1.3 【了解】编译安装的过程

切菜备菜 ./configure
炒菜 make
上菜 make install

1.4 如何向变量中存放内容—-【read命令】

1.4.1 read命令使用

  1. [root@znix ~]# read a
  2. 惨绿少年
  3. [root@znix ~]# echo $a
  4. 惨绿少年

1.4.2 让执行命令后出现提示信息

-p 为显示提示信息。p作为输出,一定要写在其他参数的最后面。

  1. [root@znix ~]# read -p "请输入:" a
  2. 请输入:呵呵
  3. [root@znix ~]# echo $a
  4. 呵呵

1.4.3 设置等待(超时)的时间

-t5 等待5秒

  1. [root@znix ~]# read -t5 -p "请输入密码:" a
  2. 请输入密码:
  3. [root@znix ~]#
  4. [root@znix ~]# read -t5 -p "请输入密码:" a
  5. 请输入密码:123

1.4.4 不显示输入的内容

-s 输入的时候不显示输入内容。

  1. [root@znix ~]# read -s -t50 -p "请输入密码:" a
  2. 请输入密码:
  3. [root@znix ~]# echo $a
  4. admin

1.5 将read命令运用到脚本上

1.5.1 修改计算器脚本的内容,让他能够更智能。

  1. [root@znix ~]# vim /server/scripts/cal.sh
  2. #!/bin/bash
  3. read -p "input 1st num:" a
  4. read -p "input 2st num:" b

1.5.2 测试脚本

  1. [root@znix ~]# sh /server/scripts/cal.sh
  2. input 1st num:1
  3. input 2st num:2
  4. 0.5
  5. 3
  6. -1
  7. 2

1.5.3 简化命令

1.5.3.1 read 可以同时读入多个字符。

  1. [root@znix ~]# read -p "输入第一个 第二关数字:" a b
  2. 输入第一个 第二关数字:123 456
  3. [root@znix ~]# echo aab
  4. 123 456

1.5.3.2 修改脚本的内容。

使用一条read命令,读取两个参数。

  1. [root@znix ~]# vim /server/scripts/cal.sh
  2. #!/bin/bash
  3. read -p "input 1st&2st num:" a b
  4. awk -vnum1=avnum2=avnum2=b 'BEGIN{print num1/num2}'
  5. awk -vnum1=avnum2=avnum2=b 'BEGIN{print num1+num2}'
  6. awk -vnum1=avnum2=avnum2=b 'BEGIN{print num1-num2}'
  7. awk -vnum1=avnum2=avnum2=b 'BEGIN{print num1*num2}'
  8. "/server/scripts/cal.sh" 15L, 355C written

1.5.3.3 测试脚本。

⚠注意 : 同时传入两个参数的时候,参数之间要使用空格分割.

  1. [root@znix ~]# sh /server/scripts/cal.sh
  2. input 1st&2st num:1 2
  3. 0.5
  4. 3
  5. -1
  6. 2

第2章 判断一个 文件/目录 是否存在

2.1 几种思路:

cat + $?’
ls + $?
test命令

2.2 test命令实例

test命令不会自己输出执行的结果,配合$?查询上一条命令是否执行成功,就能够判断是否存在这个文件或目录.

2.2.1 判断一个文件是否存在

-f 为判断的对象是文件,0为存在,1为不存在

  1. [root@znix ~]# test -f /clsn/clsn.txt
  2. [root@znix ~]# echo $?
  3. 0
  4. [root@znix ~]# test -f /clsn/clsn
  5. [root@znix ~]# echo $?
  6. 1

2.2.2 判断一个目录是否存在

-d 为对目录进行判断,0为存在,1为不存在.

  1. [root@znix ~]# test -d /znix
  2. [root@znix ~]# echo $?
  3. 1
  4. [root@znix ~]# test `-d /clsn/
  5. [root@znix ~]# echo $?
  6. 0

2.3 使用 [ ] 进行判断

⚠使用[ ]的时候注意中间的空格,两边都要有两个空格
[ ]与test命令的功能相似,可以进行判断,相比test命令更为便捷

2.3.1 [ ]判断一个文件是否存在

与test命令一样 [ ] 判断的结果也0为存在,1为不存在

  1. [root@znix ~]# [ -f /zinx.txt ]
  2. [root@znix ~]# echo $?
  3. 1
  4. [root@znix ~]# [ -f /root/clsn.txt ]
  5. [root@znix ~]# echo $?
  6. 0

2.3.2 判断成功后,执行下一个命令 &&

判断文件/目录是否存在,判断成功执行后面的内容,输出ok ;判断失败,不执行后面的命令.

  1. [root@znix ~]# [ -f /clsn/znix.txt ] && echo "ok"
  2. [root@znix ~]# [ -d /clsn ] && echo "ok"
  3. ok

2.3.3 判断不成功后执行下一条命令 ||

如果这个文件不存在,就创建 (使用 || ), || 表示前面的执行错误了,执行后面的命令.

  1. [root@znix ~]# [ -f /clsn/znix.txt ] || touch /clsn/znix.txt
  2. [root@znix ~]# ls -l /clsn/znix.txt
  3. -rw-r--r-- 1 root root 0 Sep 20 10:31 /clsn/znix.txt

2.3.3.1 [示例1]如果/root/clsndir 目录不存在就创建

  1. [root@znix ~]# [ -d /root/clsndir ] || mkdir -p /root/clsndir
  2. [root@znix ~]# ls -ld /root/clsndir
  3. drwxr-xr-x 2 root root 4096 Sep 20 10:36 /root/clsndir

2.3.3.2 [示例2]如果/root/clsndir 目录不存在,就创建这个目录

使用 && ,前面的执行成功,执行后面的; ! 表示非,不存在.

  1. [root@znix ~]# [ ! -d /root/clsndir/1 ] && mkdir -p /root/clsndir/1
  2. [root@znix ~]# ll -d /root/clsndir/1
  3. drwxr-xr-x 2 root root 4096 Sep 20 10:41 /root/clsndir/1

第3章 判断在脚本的使用

3.1.1 中文示例(更好理解)

如果 [ 这个文件存在 ];然后
提示文件存在
否则
创建这个文件
果如

3.2 [示例]判断文件是否存在,不存在就创建

3.2.1 第一步 按照格式书写判断语句

  1. if [ -f /root/clsn.txt ];then
  2. echo "文件存在"
  3. else
  4. touch /root/clsn.txt
  5. fi

3.3 第二步 写入脚本:

写入脚本的时候,注意脚本的基本格式.

  1. [root@znix ~]# vim /server/scripts/if.sh
  2. #!/bin/bash
  3. if [ -f /root/clsn.txt ];then
  4. echo "文件存在"
  5. else
  6. touch /root/clsn.txt
  7. fi

3.3.1 第三步 测试脚本

  1. [root@znix ~]# sh /server/scripts/if.sh
  2. 文件存在

3.4 在脚本中进行判断的格式

符号 参数 含义 英文
> -gt 大于 great than
>= -ge 大于等于 great equal
< -lt 小于 less than
<= -le 小于等于 less than or equal
== -eq 等于 equal
!= -ne / ! -eq 不等于 not equal

3.5 [实例]如果cal2.sh脚本的参数个数不等于2,就显示 “命令错误”

3.5.1 书写脚本

!= 表示判断两个是否不相等,如果不想等就显示命令错误

  1. #/bin/bash
  2. if [ $# != 2 ];then
  3. echo "命令错误"
  4. fi

3.5.2 对脚本进行测试.

当参数的个数为2的时候,不会输出,个数不为二的时候输出 命令错误

  1. [root@znix ~]# sh /server/scripts/cal2.sh
  2. 命令错误
  3. [root@znix ~]# sh /server/scripts/cal2.sh 1 2
  4. [root@znix ~]# sh /server/scripts/cal2.sh 1 2 3
  5. 命令错误

3.6 修改之前的计算器,进行两个数字的加减乘除,在计算器前面加上参数个数判断。当输入的参数是2个的时候执行计算,不为2的时候显示参数错误.

3.6.1 书写脚本

当输入的参数不为2的时候 执行 echo “Usage: NUM1 NUM2”, 然后执行 exit..
exit 表示前面的执行完成后就结束(跳出),不会再执行脚本后面的内容.

  1. [root@znix ~]# vim /server/scripts/cal2.sh
  2. #!/bin/bash
  3. if [ $# -ne 2 ];then
  4. echo "Usage: NUM1 NUM2"
  5. exit
  6. fi
  7. a=$1
  8. b=$2
  9. awk -vh=avz=avz=b 'BEGIN{print h/z}'
  10. awk -vh=avz=avz=b 'BEGIN{print h+z}'
  11. awk -vh=avz=avz=b 'BEGIN{print h-z}'
  12. awk -vh=avz=avz=b 'BEGIN{print h*z}'

3.6.2 测试脚本

当输入的参数个数不为2的时候执行echo 命令
当输入的参数个数为2的时候进行计算

  1. [root@znix ~]# sh /server/scripts/cal2.sh
  2. Usage: NUM1 NUM2 ##提示信息
  3. [root@znix ~]# sh /server/scripts/cal2.sh 22 22
  4. 1
  5. 44
  6. 0
  7. 484

第4章 循环语句

4.1 [示例]修改系统时间为20170501到20170520,然后创建文件的名字为2017-05-01.txt

4.1.1 基础姿势

4.1.1.1 for循环可以从后面的数组中读取内容进行操作

循环的格式 :

  1. for hd in znix_{a..z}
  2. do
  3. echo $hd
  4. done

4.1.1.2 执行for 循环语句

  1. [root@znix ~]# for hd in znix_{a..z}
  2. > do
  3. > echo $hd
  4. > done
  5. znix_a
  6. znix_b
  7. znix_c
  8. znix_d
  9. ……
  10. znix_z

4.1.2 书写循环语句

do里面可以两条命令同时执行.

  1. for hd in {01..20}
  2. do
  3. date -s "201705$hd"
  4. touch /tmp/date/$(date +%F).txt
  5. done

4.1.3 测试循环语句

  1. [root@znix ~]# for hd in {01..20}
  2. > do
  3. > date -s "201705$hd"
  4. > touch /tmp/date/$(date +%F).txt
  5. > done
  6. Mon May 1 00:00:00 CST 2017
  7. Tue May 2 00:00:00 CST 2017
  8. Wed May 3 00:00:00 CST 2017
  9. ……
  10. Sat May 20 00:00:00 CST 2017

4.1.4 检查执行结果

  1. [root@znix ~]# ls /tmp/date/
  2. 2017-05-01.txt 2017-05-05.txt 2017-05-09.txt 2017-05-13.txt 2017-05-17.txt
  3. 2017-05-02.txt 2017-05-06.txt 2017-05-10.txt 2017-05-14.txt 2017-05-18.txt
  4. 2017-05-03.txt 2017-05-07.txt 2017-05-11.txt 2017-05-15.txt 2017-05-19.txt
  5. 2017-05-04.txt 2017-05-08.txt 2017-05-12.txt 2017-05-16.txt 2017-05-20.txt

4.2 [实例]优化linux开机启动项目-for循环方法

4.2.1 第一步:确定目标

  1. for name in 要关闭的服务的名字
  2. do
  3. chkconfig $name off
  4. done

4.2.2 第二步:取出要关闭服务的名字

  1. [root@znix ~]# chkconfig |egrep -v "sshd|network|crond|rsyslog|sysstat"|awk '{print $1}'
  2. abrt-ccpp
  3. abrtd
  4. acpid
  5. ……

4.2.3 第三步 把名字与for循环结合

  1. for name in `chkconfig |egrep -v "sshd|network|crond|rsyslog|sysstat"|awk '{print $1}'`
  2. do
  3. chkconfig $name off
  4. done

第5章 脚本执行排错

5.1 sh -x 显示脚本详细的执行过程

  1. 前面有 + 表示执行过的命令的<br /> 前面没有东西,表示输出到屏幕上的内容。
  1. [root@znix ~]# sh -x /server/scripts/cal2.sh
  2. + '[' 0 -ne 2 ']'
  3. + echo 'Usage: NUM1 NUM2'
  4. Usage: NUM1 NUM2
  5. + exit

5.1.1 检查脚本运行中的错误

  1. [root@znix ~]# sh -x /server/scripts/cal2.sh 10 20
  2. + '[' 2 -ne 2 ']'
  3. + a=10
  4. + b=20
  5. + awk -vh=10 -vz=20 'BEGIN{print h/z}'
  6. 0.5
  7. + awk -vh=10 -vz=20 'BEGIN{print h+z}'
  8. 30
  9. + awk -vh=10 -vz=20 'BEGIN{print h-z}'
  10. -10
  11. + awk -vh=10 -vz=20 'BEGIN{print h*z}'
  12. 200

第6章 vim 快捷键

ctrl + v 按d批量删除
ctrl + v 按x批量删除
dd 删除光标所在行
dG 删除光标所在行到最后一行
D 光标所在位置到行尾的内容
x 删除光标所在位置的一个字符

第7章 昨日回顾

7.1 【sed命令】删除文件中的空行或只有空格的行。

7.1.1 文件内容

  1. [root@znix ~]# cat -A test.txt
  2. znix$
  3. $
  4. linux$
  5. $
  6. good$
  7. $
  8. n$

7.1.2 * 表示前一个字符出现了0次或以上

0次的时候即为^$ 表示空行,以上表示空格的行

  1. [root@znix ~]# sed '/^ *$/d' test.txt
  2. znix
  3. linux
  4. good
  5. n

7.1.3 +表示连续出现至少一次

  1. [root@znix ~]# sed -r '/^ +$|^$/d' test.txt
  2. znix
  3. linux
  4. good
  5. n

7.1.4 !表示取反

  1. [root@znix ~]# sed -n '/^ *$/!p' test.txt
  2. znix
  3. linux
  4. good
  5. n

7.1.5 同样用来取反

  1. [root@znix ~]# sed -nr '/^|+|+/!p' test.txt
  2. znix
  3. linux
  4. good
  5. n

7.2 shell编程中的变量

7.2.1 特殊变量(shell脚本中)

1,1,2… 用来传递参数
$0 脚本文件的文件名
$# 脚本中参数的个数
$? 前一条命令是否执行成功

7.2.2 全局变量(环境变量)

常用的 LANG PATH PS1 ……

7.2.3 普通变量

自己定义的变量

7.3 shell编程中与用户有关的环境变量的文件和目录

  1. /etc/profile
  2. /etc/profile.d (目录)
  3. /etc/bashrc
  4. ~/.bashrc
  5. ~/.bash_profile