[关闭]
@mrz1 2017-12-04T00:42:37.000000Z 字数 9345 阅读 681

2017-11-24课程笔记(bash find)

笔记


Bash的文件测试

存在性测试

  1. -a FILE:同-e
  2. -e FILE: 文件存在性测试,存在为真,否则为假
存在性及类别测试
  1. -b FILE:是否存在且为块设备文件
  2. -c FILE:是否存在且为字符设备文件
  3. -d FILE:是否存在且为目录文件
  4. -f FILE:是否存在且为普通文件
  5. -h FILE 或-L FILE:存在且为符号链接文件
  6. -p FILE:是否存在且为命名管道文件
  7. -S FILE:是否存在且为套接字文件

Bash的文件权限测试

文件权限测试:
  1. -r FILE:是否存在且可读
  2. -w FILE: 是否存在且可写
  3. -x FILE: 是否存在且可执行
文件特殊权限测试:
  1. -u FILE:是否存在且拥有suid权限
  2. -g FILE:是否存在且拥有sgid权限
  3. -k FILE:是否存在且拥有sticky权限

文件大小测试:

-s FILE: 是否存在且非空

文件是否打开:
  1. -t fd: fd文件描述符是否在某终端已经打开
  2. -N FILE:文件自从上一次被读取之后是否被修改过
  3. -O FILE:当前有效用户是否为文件属主
  4. -G FILE:当前有效用户是否为文件属组
  1. -z STRING 如果字符串为空,则为true
  2. -n STRING STRING如果字符串不为空,则为真。
  3. -v VAR 特殊:里面变量不加$;变量VAR是否设置;设置为真;定义空为真

判断整数

  1. test 整数1 -eq 整数2 #整数相等
  2. test 整数1 -ge 整数2 #整数1大于等于整数2
  3. test 整数1 -gt 整数2 #整数1大于整数2
  4. test 整数1 -le 整数2 #整数1小于等于整数2
  5. test 整数1 -lt 整数2 #整数1小于整数2
  6. test 整数1 -ne 整数2 #整数1不等于整数2

test用法详细介绍

双目测试:

  1. FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
  2. FILE1 -nt FILE2: FILE1是否新于FILE2mtime
  3. FILE1 -ot FILE2: FILE1是否旧于FILE2

判断ip是否合法

  1. [root@centos7 ~]#ip="123.23.223.23";[[ "$ip" =~ (([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ]] && echo true ||echo false
  2. true

判断数字

var=haha123 ; [[ "$var" =~ ^[0-9]+$ ]] && echo true || echo false

判断正整数

var=0123 ; [[ "$var" =~ ^0*[1-9][0-9]*$ ]] && echo true || echo false

手机号

mobile=12800138000 ;[[ "$mobile" =~ ^1[3456789][0-9]{9}$ ]] && echo true || echo false

Bash的组合测试条件

第一种方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[[ -r FILE ]] && [[ -w FILE ]]
第二种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行

习题练习1:

1.写脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
命令:

  1. #! /bin/bash
  2. # ------------------------------------------
  3. # Filename: $1
  4. ......省略
  5. # ------------------------------------------
  6. [ $# -lt 1 ] && echo "至少一个参数" && exit 20
  7. [ -e $1 ] && echo `grep -c '^$' $1` || echo "没有这样的文件或目录?"

执行结果:

  1. [root@centos7 ~]# ./srgsnum.sh /etc/passwd
  2. 0
  3. [root@centos7 ~]# ./srgsnum.sh
  4. 至少一个参数

2.编写脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户"该IP地址不可访问"

  1. #! /bin/bash
  2. # ------------------------------------------
  3. # Filename: houstping.sh
  4. ...... //省略
  5. # ------------------------------------------
  6. [ $# -ne 1 ] && echo "please input one ip" && exit 2
  7. ping -c1 -w1 $1 &> /dev/null && echo "ping successful" || echo "ping failed"

运行结果:

  1. [root@centos7 ~]#./houstping.sh 47.93.96.256
  2. ping failed
  3. [root@centos7 ~]#./houstping.sh 47.93.96.29
  4. ping successful

3. 编写脚本/root/bin/checkdisk.sh,检查磁盘分区空间和inode使用率,如果超过80%,就发广播警告空间将满
参考1:

  1. #! /bin/bash
  2. # ------------------------------------------
  3. # Filename: dist.sh
  4. ...... //省略
  5. # ------------------------------------------
  6. dist=`(df -i /dev/sd*;df /dev/sd*)|egrep -o '[0-9]+%' |egrep -o '[0-9]+'|sort -nr| hea
  7. d -1`
  8. [ "$dist" -gt 10 ] && wall "disk will be full"

运行结果:

  1. [root@centos7 ~]#./dist.sh
  2. Broadcast message from root@centos7.qifei.com (pts/1) (Sun Nov 26 13:33:05 2017):
  3. disk will be full

参考2:

  1. #! /bin/bash
  2. # ------------------------------------------
  3. # Filename: dist.sh
  4. ...... //省略
  5. # ------------------------------------------
  6. dist=`df |grep "/dev/sd" |grep -o '[0-9]*%' |grep -o '[0-9]*'|sort -nr| head -1`
  7. inode=`df -i |grep "/dev/sd" |egrep -o '[0-9]*%' |egrep -o '[0-9]*'|sort -nr| head -1`
  8. sum=80
  9. [ "$dist" -ge "$sum" ] && echo -e "磁盘空间占用率超过"$sum"\a `wall 'The disk space will be full' `"||echo ">
  10. 磁盘利用率为"$dist",可以使用"
  11. [ "$inode" -ge "$sum" ] && echo -e "inode占用率超过"$sum"\a `wall 'The disk space will be full'`" ||echo "ino
  12. de利用率为"$inode",可以使用"

运行结果:

  1. [root@centos7 ~]#./dist.sh
  2. 磁盘利用率为16,可以使用
  3. inode利用率为1,可以使用

参考3:

  1. #! /bin/bash
  2. # ------------------------------------------
  3. # Filename: warning.sh
  4. ...... //省略
  5. # ------------------------------------------
  6. echo `df |grep "/dev/sd" |grep -o "\<[[:digit:]]\{1,3\}%" |grep -o "[[:digit:]]\{1,3\}" |sort -nr`

运行结果:

  1. [root@centos7 ~]#./warning.sh
  2. 16 8 1

习题练习2:

1.编写脚本/bin/per.sh,判断当前用户对指定的参数文件,是否不可读并且不可写

[ ! \( -r "$1" -o -w "$1" \) ] && echo "不可读不可写"

2.编写脚本/root/bin/excute.sh,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件

3.编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统

touch /etc/nologin && echo "no" > /etc/nologin //禁止登陆
rm /etc/nologin //开启登陆

使用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量

  1. -p 指定要显示的提示
  2. -s 静默输入,一般用于密码
  3. -n N 指定输入的字符长度N
  4. -d ‘字符’ 输入结束符
  5. -t N TIMEOUTN
  6. read 从标准输入中读取值,给每个单词分配一个变量
  7. 所有剩余单词都被分配给最后一个变量
  8. read -p "Enter a filename: " FILE

鸡兔同笼问题?

  1. [root@centos7 ~]#cat checkdisk.sh
  2. #! /bin/bash
  3. # ------------------------------------------
  4. # Filename: checkdisk.sh
  5. ......省略
  6. # ------------------------------------------
  7. echo "鸡兔同笼问题?"
  8. read -p "请输入头:" head
  9. read -p "请输入脚:" foot
  10. c=$[( foot - head*2 ) /2 ]
  11. r=$[ head - $c ]
  12. echo "兔子:$c"
  13. echo "鸡: $r"

判断输入是yes 或 no ?

脚本1:

  1. #! /bin/bash
  2. # -----------------------------------------
  3. # Filename: yesno.sh
  4. ......省略
  5. # ------------------------------------------
  6. read -p "yes or no: " yn
  7. yn=$(echo $yn | tr "[:upper:]" "[:lower:]")
  8. echo $yn
  9. [ "$yn" = "yes" -o "$yn" = "y" ] && echo " you enter yes" && exit 1
  10. [ "$yn" = "no" -o "$yn" = "n" ] && echo "you enter no" && exit 2 || echo "you enter
  11. wrong" && exit 3

输出结果:

  1. [root@centos7 ~]#./yesno.sh
  2. yes or no: no
  3. no
  4. you enter no
  5. [root@centos7 ~]#./yesno.sh
  6. yes or no: yes
  7. yes
  8. you enter yes
  9. [root@centos7 ~]#./yesno.sh
  10. yes or no: asd
  11. asd
  12. you enter wrong

脚本2:

  1. [root@centos7 ~]#yn=n;[[ "$yn" =~ ^[Yy]([eE][sS])?$|^[Nn][oO]?$ ]] && echo true
  2. true
  3. [root@centos7 ~]#yn=y;[[ "$yn" =~ ^[Yy]([eE][sS])?$|^[Nn][oO]?$ ]] && echo true
  4. true
  5. [root@centos7 ~]#yn=Y;[[ "$yn" =~ ^[Yy]([eE][sS])?$|^[Nn][oO]?$ ]] && echo true
  6. true
  7. [root@centos7 ~]#yn=N;[[ "$yn" =~ ^[Yy]([eE][sS])?$|^[Nn][oO]?$ ]] && echo true
  8. true
  9. [root@centos7 ~]#yn=Yn;[[ "$yn" =~ ^[Yy]([eE][sS])?$|^[Nn][oO]?$ ]] && echo true
bash如何展开命令行--优先级

把命令行分成单个命令词

展开别名
展开大括号的声明({})
展开波浪符声明(~)
命令替换$() 和 ``)
再次把命令行分成命令词
展开文件通配(*、 ?、 [abc]等等)
准备I/0重导向(<、 >)
运行命令

防止扩展

反斜线(\)会使随后的字符按原意解释

  1. [root@centos7 ~]# echo Your cost: \$5.00
  2. Your cost: $5.00
加引号来防止扩展
• 单引号(')防止所有扩展
• 双引号(")也防止所有扩展,但是以下情况
例外:
线 上一条命令最后一个参数
!! 整个上一条命令

bash的配置文件

按生效范围划分,存在两类:

全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc

shell登录两种方式

交互式登录:
(1)直接通过终端输入账号密码登录
(2)使用“su - UserName” 切换的用户
执行顺序:/etc/profile -->/etc/profile.d/*.sh -->
~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登录:
(1)su UserName
(2)图形界面下打开的终端
(3)执行脚本
(4)任何其它的bash实例
执行顺序: ~/.bashrc --> /etc/bashrc -->/etc/profile.d/*.sh

Profile类

按功能划分,存在两类:
profile类和bashrc类
profile类:为交互式登录的shell提供配置

全局:/etc/profile, /etc/profile.d/*.sh

个人:~/.bash_profile

功用:
(1) 用于定义环境变量
(2) 运行命令或脚本

bashrc类:为非交互式和交互式登录的shell提供配置

全局:/etc/bashrc
个人:~/.bashrc
功用:
(1) 定义命令别名和函数
(2) 定义本地变量

编辑配置文件生效

修改profile和bashrc文件后需生效
两种方法:
1. 重新启动shell进程
2. 或source //是在当前变量中;bash是开了进程
例:
. ~/.bashrc

Bash 退出任务

保存在~/.bash_logout文件中(用户)
在退出登录shell时运行

用于
• 创建自动备份
• 清除临时文件

# ~/.bash_logout //里面可以写系统退出执行的命令

$-变量

h:hashall,打开这个选项后,Shell 会将命令所在的路径

hash下来,避免每次都要查询。通过set+h将h选项关闭通过set-h将h选项开启
i:interactive-comments,包含这个选项说明当前的 shell是一个交互式的shell。所谓的交互式shell,在脚本中,i选项是关闭的。
m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。
B:braceexpand,大括号扩展
H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,
"!n"返回第 n 个历史命令

练习题:

1.让所有用户的PATH环境变量的值多出一个路径,例如:/usr/local/apache/bin

全局:/etc/profile, /etc/profile.d/*.sh

2.用户root登录时,将命令指示符变成红色,并自动启用如下别名:rm='rm –i'

cdnet='cd /etc/sysconfig/network-scripts/'
editnet='vim /etc/sysconfig/network-scripts/ifcfg-eth0'
editnet='vim /etc/sysconfig/network-scripts/ifcfgeno16777736 或 ifcfg-ens33 ' (如果系统是CentOS7)

  1. [root@centos7 ~]#vim /etc/profile.d/env.sh //定义颜色
  2. PS1="\[\e[1;35m\][\u@\h \W]\\$\[\e[0m\]"
  1. echo -e "alias cdnet='cd /etc/sysconfig/network-scripts/'\n alias editnet='vim /etc/sysconfig/network-scripts/ifcfg-eth0'\n alias editnet='vim /etc/sysconfig/network-scripts/ifcfgeno16777736'" >> ~/.bashrc

3.任意用户登录系统时,显示红色字体的警示提醒信息“Hi,dangerous!”

  1. [root@centos7 ~]#vim /etc/profile.d/danger.sh
  2. echo -e "\033[1;5;31;42mHi,dangerous!\033[0m"

4.编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等

  1. #! /bin/bash
  2. cat <<_EOF_ > $1
  3. #! /bin/bash
  4. # ------------------------------------------
  5. # Filename: $1
  6. # Revision: 1.0
  7. # Date: `date +%F`
  8. # Author: Zhang Qi Fei
  9. # Email: 1353250703@qq.com
  10. # Website: www.zhangqifei.top
  11. # Description: This is the first script
  12. # ------------------------------------------
  13. _EOF_
  14. chmod +x $1
  15. vim + $1

5.编写用户的环境初始化脚本reset.sh,包括别名,登录提示符,vim的设置,环境变量等

loading......

文件查找

在文件系统上查找符合条件的文件
文件查找:locate, find
非实时查找(数据库查找):locate
实时查找:find

locate

1.查询系统上预建的文件索引数据库
/var/lib/mlocate/mlocate.db

2.依赖于事先构建的索引

索引的构建是在系统较为空闲时自动进行(周期性任务),管理员手动更新数据库(updatedb)

3.索引构建过程需要遍历整个根文件系统,极消耗资源

工作特点:
• 查找速度快
• 模糊查找
• 非实时查找
• 搜索的是文件的全路径,不仅仅是文件名
• 可能只搜索用户具备读取和执行权限的目录

locate KEYWORD

有用的选项
-i 不区分大小写的搜索
-n N 只列举前N个匹配项目
-r 使用正则表达式

示例:
搜索名称或路径中带有"conf"的文件
locate conf
使用Regex来搜索以".conf"结尾的文件
locate -r '\.conf$'

find

实时查找工具,通过遍历指定路径完成文件查找

工作特点:
• 查找速度略慢
• 精确查找
• 实时查找
• 可能只搜索用户具备读取和执行权限的目录

语法:
find [OPTION]... [查找路径] [查找条件] [处理动作]
查找路径:指定具体目标路径;默认为当前目录
查找条件:指定的查找标准,可以文件名、大小、类型、权限等标准进行;默认为找出指定路径下的所有文件
处理动作:对符合条件的文件做操作,默认输出至屏幕

查找条件

指搜索层级
-maxdepth level最大搜索目录深度,指定目录为第1级
-mindepth level 最小搜索目录深度
根据文件名和inode查找:

  1. -name "文件名称":支持使用glob
  2. *, ?, [], [^]
  3. -iname "文件名称":不区分字母大小写
  4. -inum n inode号查找
  5. -samefile name 相同inode号的文件
  6. -links n 链接数为n的文件
  7. -regex "PATTERN":以PATTERN匹配整个文件路径字符串,而不仅仅是文件名称

根据属主、属组查找:

  1. -user USERNAME:查找属主为指定用户(UID)的文件
  2. -group GRPNAME: 查找属组为指定组(GID)的文件
  3. -uid UserID:查找属主为指定的UID号的文件
  4. -gid GroupID:查找属组为指定的GID号的文件
  5. -nouser:查找没有属主的文件
  6. -nogroup:查找没有属组的文件

根据文件类型查找:

  1. -type TYPE:
  2. f: 普通文件
  3. d: 目录文件
  4. l: 符号链接文件
  5. s:套接字文件
  6. b: 块设备文件
  7. c: 字符设备文件
  8. p: 管道文件

组合条件:

  1. 与:-a
  2. 或:-o
  3. 非:-not, !
  4. 德·摩根定律:
  5. (非 A) (非 B) = 非(A B)
  6. (非 A) (非 B) = 非(A B)
  7. 示例:
  8. !A -a !B = !(A -o B)
  9. !A -o !B = !(A -a B)

find示例

  1. find -name snow.png
  2. find -iname snow.png
  3. find / -name “*.txt
  4. find /var name “*log*”
  5. find -user joe -group joe
  6. find -user joe -not -group joe
  7. find -user joe -o -user jane
  8. find -not \( -user joe -o -user jane \)
  9. find / -user joe -o -uid 500

习题:

找出/tmp目录下,属主不是root,且文件名不以f开头的文件
find /tmp \( -not -user root -a -not -name 'f*' \) -ls
find /tmp -not \( -user root -o -name 'f*' \) –ls
排除目录示例:
查找/etc/下,除/etc/sane.d目录的其它所有.conf后缀的文件
find /etc -path '/etc/sane.d' -a -prune -o -name "*.conf"
查找/etc/下,除/etc/sane.d和/etc/fonts两个目录的其它所有.conf后缀的文件
find /etc \(–path ‘/etc/sane.d’ –o –path ’/etc/fonts’ \) -a -prune –o -name "*.conf"

根据文件大小来查找:

  1. -size [+|-]#UNIT
  2. 常用单位:k, M, Gcbyte
  3. #UNIT: (#-1, #]
  4. 如:6k 表示(5k,6k]
  5. -#UNIT:[0,#-1]
  6. 如:-6k 表示[0,5k]
  7. +#UNIT:(#,∞)
  8. 如:+6k 表示(6k,∞)
  9. 查找50-100M文件?
  10. find / -size +50M -size -101M

根据时间戳:

以"天"为单位;

  1. -atime [+|-]#,
  2. #: [#,#+1)
  3. +#: [#+1,∞]
  4. -#: [0,#)
  5. -mtime
  6. -ctime
  7. 以“分钟”为单位:
  8. -amin
  9. -mmin
  10. -cmin
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注