bash 脚本基础和查找find

1 shell 基础

  • shell 脚本的用途
    1 自动化常用命令
    2 执行系统管理和故障排除
    3 创建简单的应用程序
    4 处理文本或文件
#程序=指令+数据
程序编程的风格
  - 过程式:以指令为中心,数据服务于指令
  - 对象式: 以数据为中心,指令服务于数据 
shell程序:提供编程能力,解释执行
#shell 脚本
  包含一些命令的或声明,并符合一定格式的文本文件
一般格式 首行是shebnag机制
  - #!/bin/bash
  - #!/usr/bin/python
  - #!/usr/bin/perl
  • shell 脚本的变量
不同于java,c,c# 数据类型是强类型
shell的变量类型的定义是弱类型
变量:命名的存储空间
数据的存储方式
    字符 
    数值:整形,浮点型
#shell变量
  按照变量的生效范围可划分为
本地变量:生效范围是当前shell进程,对当前shell之外的其他shell继承,包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子shell
局部变量:生效范围为当前shell进程中某代码片段(通常指的是函数)
位置变量:$1,$2,...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量:$?,$0,*,$@,$#,$$
    $0指的是命令的本身
    $* 传递所有给脚本的所有参数,全部参数合为一个字符串
    $@ 传递给脚本所有的参数,每个参数为独立的字符串
    $# 传递给脚本的参数的个数
          $@ $* 只有被双引号包起来的时候才会有差异
    set 可以设置或清空变量 
  • bash shell算术运算
1 let var=算术表达式
2 var=$[算术表达式]
3 var=$((算术表达式))
4 var=$(expr arg1 arg2 arg3 ...) 注意参数间有空格
5 declare -i var=数值
6 echo  '算术表达式' | bc
1 、编写脚本/root/bin/sumid.sh ,计算/etc/passwd 文件中
的第10 个用户和第20 用户的ID 之和
#!/bin/bash
A=`cat /etc/passwd | head -10 | tail -1 | cut -d: -f3`
B=`cat /etc/passwd | head -20 | tail -1 | cut -d: -f3`
let C=$A+$B
echo $C
unset A B
2 、编写脚本/root/bin/sumspace.sh ,传递两个文件路径作
为参数给脚本,计算这两个文件中所有空白行之和
#!/bin/bash
if [ $# = 0 ];then
    echo "please enter two file path!!"
    exit 1
else
    A=`cat $1 | grep -c '^$'`
    B=`cat $2 | grep -c '^$' `
    echo $[$A+$B]
fi
unset A B
3 、编写脚本/root/bin/sumfile.sh, 统计/etc, /var, /usr目 目
录中共有多少个一级子目录和文件
#!/bin/bash
A=`ls -l /etc/ | wc -l`
B=`ls -l /var/ | wc -l`
C=`ls -l /usr/ | wc -l`
echo $[$A+$B+$C]
unset A B C
  • bash的条件测试
测试命令
  test EXPRESSION 真,返回1,假,返回0
  [ EXPRESSION ]  真,返回1,假,返回0,和上面命令一样 一般用个,不用上面那个
  [[ EXPRESSION ]] 可以使用正则表达式的测试命令
数值测试
  -gt 是否大于
  -ge 是否大于等于
  -eq 是否等于
  -ne 是否不等于
  -lt 是否小于
  -le 是否小于等于
字符串测试
  == 是否等于
  > 是否大于
  < 是否小于
  != 是否不等于
  =~ 左侧字符串是否能够被右侧的正则表达式匹配
1 、编写脚本/root/bin/argsnum.sh ,接受一个文件路径作为
参数;如果参数个数小于1 ,则提示用户“至少应该给一个参
数”,并立即退出;如果参数个数不小于1 ,则显示第一个参
数所指向的文件中的空白行数
#!/bin/bash
if [ $# -eq 0 ];then
    echo "please enter one argument"    
    exit 1
else
    grep -c "^$" $1;
fi
2 、编写脚本/root/bin/hostping.sh ,接受一个主机的IPv4
地址做为参数,测试是否可连通。如果能ping 通,则提示用户
“该IP 地址可访问” ;如果不可ping 通,则提示用户“该IP地 地
址不可访问”
#!/bin/bash
if [ $# -eq 0 ];then
    echo "please enter one IPV4 address"
    exit 1
else
    ping -c2 -w1 $1 &> /dev/null
    if [ $? -eq 0 ];then
        echo "the host can connect!"
    else
        echo "the host can not connect!"
    fi
fi

3 、编写脚本/root/bin/checkdisk.sh ,检查磁盘分区空间和
inode 使用率,如果超过80%,就发广播警告空间将满
#!/bin/bash
A=`df | egrep -o '[0-9]{1,3}%' | sort -nr | head -1 | cut -d% -f1`
B=`df -i | egrep -o '[0-9]{1,3}%' | sort -nr | head -1 | cut -d% -f1`
if [ $A -gt 30 -o $B -gt 30 ];then
    wall disk is full
fi
unset A B
  • bash的文件测试
# 存在性测试
  -a FILE: 同-e
  -e FILE: 文件存在性测试,存在为真,否则 为假
# 存在性及类别测试
  -b FILE: 是否存在且为块 设备文件
  -c FILE: 是否存在且为字符 设备文件
  -d FILE: 是否存在且为 目录文件
  -f FILE: 是否存在且为 普通文件
  -h FILE 或 或 -L FILE :存在且为符号 链接文件
  -p FILE : 是否存在且为命名 管道文件
  -S FILE : 是否存在且为套接

#文件权限测试
  -r FILE: 是否存在且可读
  -w FILE: 是否存在且可写
  -x FILE: 是否存在且可执行
#文件特殊权限测试:
  -u FILE : 是否存在且拥有suid 权限
  -g FILE: 是否存在且拥有sgid 权限
  -k FILE: 是否存在且拥有sticky 权限
#文件大小测试:
  -s FILE: 是否存 在 且 非空
#文件是否打开:
  -t fd: fd 表示文件描述符是否已经打开且与某终端相关
  -N FILE : 文件自动上一次被读取之后是否被修改过
  -O FILE : 当前有效用户是否为文件属主
  -G FILE : 当前有效用户是否为文件属组
1 、编写脚本/bin/per.sh, 判断当前用户对指定的参数文件,
是否不可读并且不可写
#!/bin/bash
if [ ! -e $1 ];then
    echo "please enter a filepath or the file is not exist"
    exit 3
else
    if [ ! -w $1 -a ! -r $1 ];then 
        echo "you have not permision to write and read"
    else 
        echo "you have permission to write or read"
    fi
fi

2 、编写脚本/root/bin/excute.sh  ,判断参数文件是否为sh
后缀的普通文件,如果是,添加所有人可执行权限,否则提
示用户非脚本文件
#/bin/bash
if [ -f $1 ];then
#   if [[ `basename $1` =~ \.sh$ ]];then
    if [[ `basename $1` == "*.sh" ]];then
        echo "it is a normal file and end of .sh"
        chmod 777 $1
    else 
        echo " it is not end of .sh"
        exit 3
    fi
else
    echo "ist is not a nomal file"
    exit 2
fi
当用户登陆时,环境的配置顺序
    交互式登录 直接通过终端输入密码账号的路 或使用su - username 来进行用户切换
    顺序
        /etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc
    非交互是登录 su username 图形化打开的终端 执行脚本
        ~/.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh

2 文件查找 find location

locate 使用的时候是在 /var/lib/mlocalte/mlocated.db 中查找数据所以相对会快点,但是新创建的文件是找不到的
需要重新创建mlocate.db 使用uodatedb 命令即可创建新库 注意创建新库时会影响电脑的性能
locate -r "\.conf$" 可以使用正则表达式
locate -n 显示查找到的几行
find命令的使用
find . -size 6c -print  查找6个字节文件
find . -size -32 -print 查找小于32字节的文件、
find . -name 'del.txt' -ok rm {} \; 删除del.txt 删除前并提示
find . -name 'aa.txt' -exec cp {}{,.bak} \;查找aa.txt 并且cp一份名字为aa.txt.bak
find . -name 'aa.txt' -type f -exec tar -zxvf {}.tar.gz {} \; -exec rm {} \;
    查找 aa.txt归档压缩为aa.txt.tar.gz 并删除 aa.txt

find [option]  [path] [condition] [command]

option  可以使用通配符
    -not 非
    -name 以名字来查找文件
    -iname 忽略大小写查找文件
    -inum 按inode号来查找文件
    -samefile 硬链接个数
    -links # 软链接数为#的文件
    -regex 正则表达式
    -user username 查找所属主文件
    -group groupname 查找所属组的文件
    -nouser 查找没有属主的文件
    -nogroup 查找没有属组的文件
    -prune 除了 结合-path 使用
    find / -path '/path/to/somewhere' -a -prune -o -name fstab  path的最后位置上不能有/
    -size 大小  单位 的重要性 #-1  1024M-1 和1G-1 是不同的 
        +# 大余 (#,-∞)
        -# 小于 [0,#-1]
        # 等于 在 #-1 到# 之间的文件(#-1,#]
    -mtime 时间 单位:天  -atime -ctime  表示过去
        +# 大于 (#+1,-∞)
        -# [0,#)
        # [#,#+1]
    -mmin 同上   -amin -cmin  表示过去
    -perm permission (权限)
        + 或
        - 与
        find /etc /222 只要都有个写权限 centos7 -222
        find /etc +222 至少有一个写权限 cnetos6 -222 同时都拥有写权限  220 0 表示不关心(配合+ - 使用)
path
    一般是当前目录 ,也可以指定目录 可以使用 -prune 去除一些路径
condition
    -type 查找文件类型
        -f common file
        -d directory
        -l link
        -s socket
        -p pipe
        -b block
        -c character
    -maxdepth 最大搜索层级
    -mindepth 从哪个层级开始搜索 直到结束
    -path 可以筛选路径
command
    -ls 列出来
    -print 打印出来 不列出属性 ls 不加
    -delete 删除
    -fls file 查找到的所有长格式信息保存到指定文件中
    -ok 同下 做操作时会询问
    -exec {} \; 执行一些命令 如 cp  tar gz  {} 表示 前面搜索到的文件名 args参数个数不能太多 xargs 用于产生命令的参数
        xargs 的使用find |xargs command
        find /sbin -perm /700 | xargs ls -l  管道xargs 前有一个空格
1 、查找/var 目录下属主为root ,且属组为mail 的所有文件
  find /var/ -user root -group mail -ls
2 、查找/var 目录下不属于root 、lp 、gdm 的所有文件
  find /var/ -not \( -user root -o -user lp -o -user gdm \) -ls
3 、查找/var 目录下最近一周内其内容修改过,同时属主不为
root ,也不是postfix 的文件
  find /var/ -mtime -7 -not \( -user root -o -user postfix \) -ls
4 、查找当前系统上没有属主或属组,且最近一个周内曾被访
问过的文件
  find / -nouser -nogroup -mtime -7 -ls 2>/dev/null
5 、查找/etc 目录下大于1M 且类型为普通文件的所有文件
  find /etc/ -size +1M -type f  | xargs ls -lh
6 、查找/etc 目录下所有用户都没有写权限的文件
  find /etc/ -not -perm /222 -ls
7 、查找/etc 目录下至少有一类用户没有执行权限的文件
  find /etc/ -not -perm -111 -ls
8 、查找/etc/init.d 目录下,所有用户都有执行权限,且其它
用户有写权限的文件
  find /etc/init.d/ -perm -113

你可能感兴趣的:(bash 脚本基础和查找find)