ctrl  +z  暂停一个任务
jobs 查看后台任务
bg [id] 把任务调到后台运行 ,命令后面加&直接丢到后台执行
fg[id] 把后台任务调到前台
sleep  200   暂停200S
cat -A  显示隐藏字符,如换行符
tac   cat的反向输出
cd -  等价于 cd  $OLDPWD   表示进入上一次的文件目录路径
stat  获取指定文件的元数据
file  查看文件类型
tail -f  跟踪文件最新追加信息,用于log日志诊断,control + c 退出
socket ,插槽,就是通信的接口。对于互联网上两台主机之间使用IP和端口组成的socket进行通信
{} 命令行路径展开机制 
/tmp/{a,b} = /tmp/a,/tmp/b

重定向操作:
command >test.txt 2>&1   等价于  command >test.txt  2>test.txt
>a.txt   清空文件的重定向操作
echo "xxxx" | passwd --stdin username   
hash 命令:查看shell命令缓存
shell变量事先无需声明,默认是字符型
shell下变量引用:${var_name} 或 $var_name
                        “”表示弱引用,会替换为变量的值,‘’表示强引用,不会替换为变量的值
set 命令 查看变量  ,unset  撤销变量
特殊变量:$?  记录shell命令执行状态,0表示成功,非0表示失败
                 $0  脚本本身    $#   参数个数
export 查看环境变量  直接调用,常见 PATH  SHELL PWD HOME 
export  name=value 或 delare -x  name=value  声明环境变量
export声明的变量作用范围是当前shell和由当前shell衍生出来的子shell,对父shell无效
pstree :查看进程树
declare -r  或 readonly  设置为只读变量,存活周期为当前shell,当前shell终止后变量自动撤销
read  -p   读取交换式输入变量值
$REPLY  内置变量,返回输入的值



命令执行:
command1;command2;command3.......使用分号分开,各命令间无逻辑关系,顺序执行
command1&&command2&&command3   (短路运算,只要有0就结果为0)使用&&分开,前面为假则不再往下执行
command1||command2||command3     (短路运算,只要有1就结果为1) 使用||分开,前面为真则不再往下执行
异或运算,相同则为0,不同则为1

shell脚本执行  (通过启动一个新子shell运行)
绝对路径执行
相对路径执行   ./xxx.sh   ,如果直接xxx.sh表示当做命令运行,会从环境变量中查找该命令
解释执行   bash  /path/to/xxx.sh  直接把脚本当做bash的参数运行,这种情况脚本不需要执行权限

profile配置文件  (定义环境变量、运行命令或脚本,登录生效)
全局生效 /etc/profile   /etc/profile.d/*.sh
当前用户生效  ~./bash.profile

bashrc配置文件 (定义本地变量和命令别名,不需要登录,开启一个shell就可以加载)
全局/etc/bashrc
个人 ~/.bashrc
PS1(定义登录提示符样式) 、./bash_logout(定义退出时候执行某些动作)

脚本文件运行时候环境变量查找路径 (只查找这三个地方)
~/.bashrc  -----/etc/bashrc------/etc/profile.d/*
重读配置文件   source  或  .     /path/to/xxx.conf

正则表达式
匹配字符:
[:digit:]  任意单个数字
[:lower:]  任意单个小写字母
[:upper:]  任意单个大写字母
[:alpha:]   任意单个字母     
[:alnum:]  任意单个字母或数字
[:punct:]  任意单个标点符号
[:space:]  匹配空格
grep "r[[:alpha:]][[:alpha:]]t"     匹配r与t之间有任意两个字母的字符串

匹配次数:
*   匹配其前面字符的任意次
.*   匹配任意长度的 任意字符
\?  匹配其前面字符0次或1次,即前面字符可有可无
\+  匹配其前面字符1次或多次,即前面字符出现至少1次
\{m\}  匹配前面字符m次
\{m,n\}  匹配前面字符至少m次,至多n次
       \{0,n\}   匹配至多n次
        \{m,\}   匹配至少m次

位置锚定
^    行首锚定,用于模式的最左侧 
$     行尾锚定,用于模式的最右侧
^PATTERN$     用于PATTERN来匹配整行
        ^$    空白行
       ^[[:space:]]*$    空行或包含空白字符的行
单词:非特殊字符组成的连续字符都称为单词,可以包含数字
\<  或\b   词首锚定,用于单词模式的左侧
\>  或\b   词尾锚定,用于单词模式的右侧
\<PATTERN\>   匹配完整单词

grep "\<[[:digit:]]\{2,3\}\>"  /etc/passwd    查找文件中两位数或三位数
grep  "^[[:space:]]\+[^[:space:]]" /etc/xxxx   查找至少一一个空白字符开头且后面是非空白字符的行

分组及引用
" \(\) "   将一个或多个字符捆绑在一起,当做一个整体进行处理   如   \ (xy \)*ab 
引用分组    分组括号中的模式匹配到的内容会被正则引擎记录于内部变量中
\1    第一组     \2  第二组    ......
如  grep "\(l..e \).*\1" xxx.txt   后项引用,引用前面的分组括号中的模式所匹配到的字符。

egrep  支持扩展正则,于基本正则相比,字符匹配格式去除了\符号,不需要转义,位置锚定还是要转义
增加 "或表达式"   c|Cat , (c|C)at
egrep "\<[0-9]{2,3}\>"  /etc/passwd   等同于 grep "\<[0-9]\{2,3\}\>"  /etc/passwd

查找以大写或小写S开头的行,使用三种方式
grep  -i "^s" /xxx.txt
grep  "^[sS]" /xxx.txt
egrep  "^(s|S)" /xxx.txt
显示系统上root、centos、user用户的相关信息
egrep "^(root|centos|user)\>"  /etc/passwd    后面使用单词锚定
找出/etc/rc.d/init.d/functions中某单词后面跟一个小括号的行
egrep -o "[_[:alnum:]]+\(\)"  /etc/........                  注意:用grep的时候转义符加小括号会表示为分组
使用echo 命令输出一个绝对路径,使用egrep取出基名
echo /etc/sysconfig/ | egrep -o "[^/]+/?$"
进一步:取出其路径名
 echo /etc/sysconfig/fweofjweif./network |egrep "^/.*/"
找出ifconfig命令结果中1-255之间的数值
ifconfig| egrep -o "\<[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>"
找出ifconfig中的IP地址
ifconfig | grep "\<inet\>" |sed 's/^[ \t]*//g'| cut -d' ' -f2       sed中括号表示“空格或TAB制表符”
找出/etc/passwd中shell与用户名同样的行
egrep "^([^:]+\>).*\1$"   /etc/passwd
grep "^\([^:]\+\>\).*\1$" /etc/passwd

grep -E   等价于  egrep
grep -A2   打印匹配行以及前两行
grep -B2    打印匹配行以及后两行
grep -C2    打印匹配行以及前后各两行

sed 命令
sed -e 连续匹配多个条件  sed使用  /字符串/ 来匹配相应字符串
sed -e '/root/p'  -e '/user/p' -n  等价于   sed  '/root/p ; /user/p' -n
表示某行如果匹配字符串root会打印出来,然后再那user匹配该行,如果匹配再打印一次
sed  -r  支持正则
sed -n  静默模式,只打印匹配的行
sed -i  直接修改文件
sed -i '1,3s/x/y/g' /tmp/passwd.txt
sed  '10,$d'  删除从第10行到最后行的所有行
sed   -r  '/root|mysql/d'   删除包含root或mysql的行
sed   -r '/^[0-9]/d' /tmp/passwd.txt     删除以数字开头的行
sed  '1,10s/in//g' passwd.txt -n  删除1到10行中的in字符串
head passwd.txt | sed -r 's/([^:]+)(:.*:)([^:]+$)/\3\2\1/'  将第一段和最后一段位置对调,采用后项引用的方式

awk  命令
awk  -F  指定分隔符,默认空白分隔   
awk -F ':' '{print $1}' /tmp/passwd.txt
awk -F ':'  '$1~/oot/' '{print $1,$2}' passwd.txt       条件过滤'$1~/oot/',表示$1中包含oot的行
awk -F ':' '$1=="root"|| NR > 30 {print $1,$2}' passwd.txt   两个条件过滤,NR表示行,NF表示列
||  或   ,&&  与

awk -F ':'  '$1=$2+$3 {print}'  passwd.txt  
字段间的运算,print默认是print $0,就是整行打印

awk -F ':' '$1=$2+$3 {OFS="#";print$0}' passwd.txt
字段间运算,并在后面增加定界符#
$NF   最后一列
awk 'NR!=1' 007.txt    不打印第一行
awk -F ':'  'BEGIN{OFS="++";ORS="##"}{print $1,$3}'  007.txt
OFS指定输出的时候每列之间使用的分隔符,ORS 指定输出的时候每行之间使用的分隔符,默认是是回车换行符
awk  '{for (i=1;i<=NF;i++){a[NR]+=$i}}';END'{for (i  in a){print i,a[i]}}' 007.txt
首先通过for循环进行数组赋值,进行NF列循环,并把NR行的各个元素累加到a[NR]数组
然后再使用for循环打印出数组元素,(i  in  a ) 取数组索引
比如文件有5列,NF=5  ,NR=1时循环5次,把第一行每列的值累加并赋给a[1]
awk  '{if ($1 == "sun")print $0}' 007.txt
打印第一列为sun的整行($0表示打印整行)
awk '{if ($2 > 40 )print $0}'  007.txt
打印第二列大于40的行
awk '{if(length($1)>4 && $2 >50)print $0}'  007.txt
打印第一列字符长度大于4并且第二列值大于50的行
awk  计算文件的空行 ??
awk 整个处理过程分三个阶段,第一个阶段是初始化阶段,也就是读取输入文件之前,由BEGIN标识
主要用于初始化一些分隔符之类,只执行一次;第二阶段主要输入循环,对每个输入文件进行处理;第三阶段是读取输入文件
完毕,由END标识,也只执行一次。
如:
awk 'BEGIN{a=333;print a}'  007.txt  ,假定txt文件有三行,这条语句只输出了一次333,因为BEGIN语句只执行一次
同样,awk 'END{a=333;print a}' 007.txt  也是只输出一行。但是 awk 'BEGIN{a=333}{print a}'  007.txt 这个执行三次,因为
print a这个处于第二阶段的循环体中

if-else 语法
if(condition)
{then-body}
else
{[else-body]}
如:
awk -F: '{
if ($1 == "root")
    printf "%-15s: %s\n",$1,"Admin";
else
    printf "%-15s: %s\n",$1,"common user"
}'  /etc/passwd

awk -F: -v sum=0 '{
if ($3 >= 500)
    sum++
}END{
    print sum
}' /etc/passwd
-v  表示声明一个变量,也可以写到BEGIN里头
awk -F:  BEGIN{sum=0} '{
判断循环体
}'
awk -F: 'BEGIN{sum=0}{if ($3 >= 500)sum++}END{print sum}' /etc/passwd

while循环
awk -F: '{
i=1;
while (i<=3)
{print $i;i++}
}'  /etc/passwd
改写成for循环
awk -F: '{
for (i=1;i<=3;i++)
{print $i}
}' /etc/passwd


~  匹配正则表达式   !~不匹配正则表达式


cut 
-d    -f  常用选项
cut -d: -f1,5-7  /etc/passwd    指定冒号为分隔符,截取1,5到7列
wc  sort  uniq  diff  path
sort -n  按数字排序,字母和特殊符号被认为是0,排在最前面。-r 反向
uniq去重的前提是要先排序,所以一般都结合sort 使用 ,-c 统计重复次数
tee  和>类似,重定向的同时还在屏幕显示
sort  a.txt |uniq -c  | tee b.txt    将输出重定向到b.txt的同时在屏幕打印出来
tr 替换字符   tr 'a' 'b'  、tr '[a-z]' '[A-Z]'
split  切割   -b 按大小切割,默认,-l按行切割

vim
vi  visual interface     vim  vi improved
打开文件   
+num    打开后直接让光标处于第num行行首
+/PATTERN   打开后直接让光标处于第一个被PATTERN匹配到的行的行首

模式转换
    编辑模式---->插入模式:
     i    insert  在光标所在处插入
     a   append   在光标所在处后方插入
     o   在光标所在处的下方打开一个新行
     I    在光标所在处的行首插入
     A    在光标所在处的行尾插入
     O   在光标所在处的上方打开一个新行
关闭文件
ZZ    编辑模式下保存并退出
光标跳转
字符间跳转
h  左  l  右   k  上    j  下
#command   跳转#个字符
单词间跳转
w   下一个单词的词首
e    当前或后一个单词的词尾
b    当前或前一个单词的词首
#command   跳转#个单词

行首行尾跳转
^   跳转至行首第一个非空白字符
$    跳转至行尾
0    跳转至行首

行间跳转
#G    跳转至第#行
1G ,gg   跳转至第一行
G   跳转至最后一行
翻屏操作
ctrl  + f   向文件尾翻一屏
ctrl  + b   向文件首部翻一屏
ctrl  + d   向文件尾翻半屏
ctrl  + u   向文件首部翻半屏
回车键按行向后翻

vim  编辑命令
字符编辑
x   删除光标所在的字符
#x   删除光标所在处起的#个字符
xp  交换光标所在处字符于其后面的字符
替换命令
  r  替换光标所在处的字符    如 rG   就是把光标所在处字符替换为大写G
删除命令
    d   
      d$   d^   dw  de  db   
    #command
#dd  删除光标所在行为起始的#行
粘贴 操作(p,paste)
p  粘贴当前光标所在行下方
P(大写)  粘贴当前光标所在行上方

复制操作(y,yank  )
跟d 命令一样

改变命令(c,change)
与d、y操作一样,只是c命令执行时候会从编辑模式进入插入模式

可视化模式
v  按字符选定
V  按行选定
组合d c y 使用

撤销操作(u,undo)
u  撤销此前的操作
    #u  撤销此前的#个操作
撤销此前的撤销
crtl  + r
重复执行前一个编辑操作   .    点号

vim自带练习手册  vimtutor
vim 末行模式
地址定界
    :start_pos[,end_pos]     结合查找替换使用
            #    特定的第#行
             .   当前行
             $   最后一行
             #,#    指定行范围,左边是起始行,右边是结束行
             #,+#   指定行范围,左侧为起始行绝对编号,右侧为相对偏移量
                     . ,$-1    当前行到倒数第二行
                     1,$     第一行到最后一行
               %   全文
               /pattern/   从光标所在处起始向文件尾部第一次被模式匹配的行
                      /first/,$   
                /pat1/,/pat2/   从光标所在处起始,第一次匹配pat1 和pat2 之间的所有行
            可同编辑命令(d   y   c )一起使用实现编辑操作
            :w /path/to/file   将范围内的文本保存至指定的文件
            :r  /path/to/file    将指定的文件读取并插入指定的位置
查找
          /pattern    从当前光标所在处向文件尾部查找能够被当前模式匹配到的所有字符串
         ?pattern   从当前光标所在处向文件首部查找能够被当前模式匹配到的所有字符串
                n   下一个,与命令方向相同      N 上一个,与命令方向相反
          3,$/pattern   查找从第三行到最后一行匹配pattern的字符串
查找并替换
    s   末行模式的命令   使用格式
              s/要查找的内容/替换为的内容/修饰符
                         要查找的内容: 可使用正则表达式
                          替换为的内容:不可以使用正则,但可以引用
                                   如果“要查找的内容”部分在模式中使用分组符号就可以在“替换为的内容”中使用后项引用
                                    也可以直接引用查找模式匹配到的全部文本,使用&符号引用
                            修饰符:
                                   i    忽略大小写         g   全局替换,意味着一行中如果匹配到多次,则都要替换
                     可把分隔符替换为其他非常用字符,不一定使用斜杠,避免冲突
                       s@@@     s###
                  示例:
                      %s@\<t\([[:alpha:]]\+)\>@T\1@g    将全文所有t开头单词中 t变T
                     2,$s@\<t[[:alpha:]]\+\>@&er@g     将第二行到最后一行t开头单词后面加er
         练习
                1  使用查找替换命令删除/tmp/grub2.cfg 文件中以空白字符开头的行的行首空白字符
                      %s@^[[:space:]]\+@@
                 2为/tmp/functions 文件中以空白字符开头的行行首加上#号
                   %s@^[[:space:]]\+[^[:space:]]@#&@g
                 3为/tmp/grub2.cfg文件前三行的行首加上#号
                   1,3s/^.*/#&/
           4将/etc/yum.repos.d/centos-base.repo文件中所有的enabled=0 替换为enabled=1,gpgcheck=0替换为gpgcheck=1
              %s@\(enabled \| gpgcheck\)=0@\1=1@g

vim  多文件编辑功能
     vim   file 1  file2  .......
             文件间切换
               :next   下一个    :prev   上一个    :first  第一个     :last  最后一个
              退出所有文件
               :wqall   退出并保存所有     :wall      :qall
             多窗口 
                -o   水平分割窗口      -O   垂直分割窗口
                ctrl +w ,箭头     窗口间切换
              单个文件也可以分割多个窗口进行操作
                ctrl  +w  s    水平分割窗口
                 ctrl  +w  v    垂直分割窗口

  定制vim  工作特性
   全局有效配置
  /etc/vimrc
用户个人
~/.vimrc   (默认可能不存在,需要手工创建)
行号: set  nu       set  nonu
括号匹配    set showmatch  或  setsm      set nosm
自动缩进    set ai    set  noai   

bash  中的算术运算
格式
1   let  var=算术表达式    如:let  x+=1、  let  x++   增强型赋值
2   var=$[算术表达式]
3   var=$((算术表达式))
4  var=$(expr $ARG1 操作符  $ARG2)
    如:var=$(expr 3 + 4)
乘法符号在有些环境中需要使用转义符

练习:
写一个脚本,添加三个用户   求此三个用户的UID之和
#!/bin/bash
for U in userrr{1..3};do
   /usr/sbin/useradd ${U}
done
u1=`id -u userrr1`
u2=`id -u userrr2`
u3=`id -u userrr3`echo -e "The SUM is $(expr $u1 + $u2 + $u3)"

条件测试:
  测试命令: 当一个非命令的表达式需要判断时候就要加上如下测试命令,而shell 命令可以直接判断,因为有执行状态返回值
   例如:if  id $1 &> /dev/null; then  而不能写成  if  [ id $1 ]   

   test   Expression
   [  Expression  ]
   [[  Expression  ]]
  注意:Expression 前后必须有空白字符
bash测试类型:
   数值测试:
            -gt   是否大于
            -ge   是否大于等于
            -eq    是否等于
             -ne   是否不等于
              -lt    是否小于
              -le    是否小于等于
    字符串测试:
                ==   是否等于
                >      是否大于   ,ascii码值比较
                <
                  !=    是否不等于
                  =~   左侧字符串是否能够被右侧的PATTERN所匹配
                            注意:此表达式一般用于[[  ]]  中
                   -z  "STRING"   测试字符串是否为空,空则为真,不空则为假
                   -n  "STRING"   测试字符串是否不空,不空则为真,空则为假
                    注意:用于字符串比较时用到的操作数都应该使用引号
    文件测试:
            存在性测试:
                -e  或 -a   ,存在即为真,不存在为假
            存在及类别测试:
               -d   目录   -c  字符    -b  块设备  -f  普通文件.......
            文件权限测试
            文件特殊权限测试
            文件大小测试  
            -s  是否存在且非空
            文件是否打开
            -t  fd   fd表示文件描述符是否已经打开且与某终端相关
    双目测试
        file1  -ef  file2    是否指向同一个inode        
        file1  -nt  file2    file1是否新于file2
        file1  -ot  file2    file1是否旧于file2

    例子:
       [ -z  "$a"  -o  "$a"=="localhost.localdomain" ]  等价于[ -z "$a" ] || [ "$a"=="localhost.localdomain" ]

bash中自定义退出状态码
 exit  [n]    自定义退出状态码
脚本中一旦遇到exit命令,脚本会立即终止,终止退出的状态取决于exit命令后面的数字,如果
未指定退出状态码,整个脚本的退出状态码取决于脚本中最后一个命令执行的状态码。

文件查找
     命令   locate     ,find
    locate    依赖于事先构建好的索引库,系统自动实现(周期性任务),手动更新索引库updatedb
   特性:查找速度快,模糊查找,非实时查找
   locate  [option]  ....pattern
            -b:匹配基名
             -c  统计符合条件文件
             -r  bre,基本正则
         注意:索引构建过程需要遍历整个文件系统,极其消耗资源
find
      实时查找,遍历指定起始路径下文件系统层级结构完成文件查找
      工作特性:查找速度稍慢,精确查找,实时查找
   用法:
           find  [option]  [查找起始路径]  [查找条件]  [处理动作]
            查找起始路径:指定具体搜索目标起始路径,默认当前路径
            查找条件:指定查找标准,可以根据文件名、大小、类型、从属关系、权限
            处理动作:对符合条件的文件做出操作,默认是标准输出到屏幕
     根据文件名
             -name "pattern"
             -iname  "pattern"  忽略大小写
                         支持gloab风格通配符  *   ?   []   [^]   [[:space:]]  等
              -regex  pattern   正则表达式,但只匹配路径,而不是文件名
       根据文件从属关系
              -user  username
               -group  groupname
                -uid   uid
                 -gid    gid
                -nouser    查找没有属主的文件
                -nogroup
      根据文件类型
                -type  TYPE
                      f   普通文件     d  目录   l  符号链接   b 块设备   c 字符设备  p  管道    s 套接字
     组合测试
            与   -a   (默认)   或 -o    非  -not   ,!
练习       
      1,、找出/tmp目录下属主为非root的所有文件
            find /tmp -not -user root -type f
       2、找出/tmp目录下文件名中不包含fstab字符串的文件
            find /tmp -not -iname "*fstab*" -type f -ls
       3、找出/tmp目录下属主为非root,而且文件名不包含tstab字符串的文件
                    find /tmp -not -user root -not -iname "*tstab*" -type f -ls
                    find /tmp -not \( -user root -o -iname "*tstab*" \) -type f -ls     小括号转义符前有空格

                    !A -a  !B  等价于   !(A -o  B)
                     !A  -o  !B  等价于  !(A  -a  B)  

  根据文件的大小查找
                 -size [+|-]  #单位
                       常用单位:K  M G
                       #单位   (#-1 ,#]
                       -#单位  [0,#-1]
                        +#单位  (#,无穷大)
       根据时间查找
                  以天为单位
                                  -atime  [+|-] #
                                   -mtime
                                   -ctime
                     以分钟为单位
                                   -amin    - mmin  -cmin
      根据权限查找
                -perm [/ | -] mode
                          mode   精确匹配权限
                          /mode   任何一类用户(u g o )中的任何一位(r w x )都相同即满足
                                9位权限之间存在“或”关系 
                         -mode   每一类(u g o)的权限中每一位(r  w x )都符合条件即满足
                               9位权限之间存在“与”关系
                    find  ./  -not -perm -222  -ls    表示3个权限组必须都具有写权限
                    find  ./  -not -perm /222  -ls    表示至少有1个权限组有写权限
                    find  ./   -perm  /111  -ls          表示至少有一个权限组有执行权限
                    find  ./  -perm  /001  -ls     0表示不关心前面两个权限组,只要第三个权限组有执行权限
                    find  ./  -perm  001  -ls     表示精确匹配,只有第三组权限位并且只有执行权限
处理动作:
         -delete    删除查找到的文件
          -fls  /path/to/file   把查找到的所有文件的长格式信息保存至指定的文件
           -ok   cmmand {} \;   对查找到文件执行command命令,并提示 。 {}表示查找到的结果集
          -exec   command {} \;   不提示
           find  ./ -perm  /002  -exec mv  {}  {}.danger  \;     修改查找到的文件名为xxx.danger
         注意:find 传递查找到的文件路径至后面的命令时,时先查找出所有的文件,并一次性传递给后面的命令,但
          有些命令不能接受过长的参数,此时命令执行会失败。使用find  | xargs command  可规避此问题
   
xargs命令是给其他命令传递参数的一个过滤器,也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数,xargs能够处理管道或者stdin并将其转换成特定命令的命令参数。xargs也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。xargs的默认命令是echo,空格是默认定界符。这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。xargs 是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令。
cat test.txt | xargs       多行文本,默认单行输出
cat test.txt |xargs -n3      -n  分3列输出
cat test.txt | xargs -de     -d  指定分隔符为e
rm
 find .-type f  -name "*.sh" -print0 | xargs  -0 rm -f     
注意:find命令默认-print会在每行输出后加一个回车换行,而-print0则用null(\0)字符替代换行符,同样 -0 表示告诉xargs使用null字符为分隔符,这个情况主要是针对文件名中有空格的情况,因为xargs默认是以空格为分隔符,产生冲突。

练习
  1   查找  /var 目录下属主为root  且属组为mail的所有文件或目录
           find  /var  -user root -a -group mail -ls
2   查找/usr 目录下不属于root ,bin 或hadoop的所有文件或目录
     find /usr  -not -user root -a -not -user hadoop -a -not -user bin
     find  /usr  -not \(-user root -o -user bin -o -user hadoop \)  -ls
3   查找/etc目录下最近一周其内容被修改过,且属主不是root用户也不是hadoop用户的文件或目录
     find /etc  -mtime -7 -a -not \(-user root -o -user hadoop \)
4  查找当前系统上没有属主或属组,且最近一周内曾被访问过的文件或目录
     find  /  \(-nouser  -o  -nogroup\)  -atime -7  -ls
5查找/etc/目录下大于1M且类型为普通文件的所有文件
     find  /etc  -size +1M -type f  -exec ls -lh {} \;       注意: {}与\之间有空格
     find /etc -size +1M -type f | xargs du -sh
6 查找/etc 目录下所有用户都没有写权限的文件
       find  /etc/  -not  -perm  /222  -ls
7查找/etc目录至少有一类用户没有执行权限的文件
      fine  /etc -not  -perm -111  -type f  -ls
8查找 /etc/init.d目录下,所有用户都有执行权限,且其他用户有写权限的所有文件
     find  /etc  -perm  -113  -type f -ls
   注意:-113 表示只要该权限位有即可,不是完全匹配,比如其中的1,表示只要有执行权限即可,而不是只有执行权限


特殊权限  
     SUID   SGID  STICKY
   安全上下文:
         1  进程以某用户的身份运行,进程是发起此进程用户的代理,因此以此用户的身份和权限完成所有操作
         2  权限匹配模型
             判断进程的属主,是否为被访问的文件属主;如果是,则应用属主的权限,否则判断文件属组,最后判断other权限
       SUID
       默认情况下,用户发起的进程,进程的属主是其发起者,因此,其以发起者的身份在运行
       SUID的作用是当用户运行某程序时,启动后的进程属主不是发起者,而是程序文件的属主,也就是也程序文件属主身份运行
       管理文件的SUID 权限
           chmod   u+|- s   file.....
           在属主位置展示,如果属主原本有执行权限,显示为小写s,否则显示大写S
       SGID
           作用  :   当目录属组有写权限,且有SGID权限时,那么所有属于此目录的属组,且以属组身份在此目录中新建文件或目录时,新文件的属组不再是用户的基本组,而是此目录的属组
       管理SGID      chmod   g+|-s   file.......

   Sticky 
       作用: 对于属组或全局可写的目录,组内的所有用户或系统上的所有用户对在此目录中都能创建新文件或删除所有的文件;如果此类目录设置了sticky权限,则每个用户在创建新文件的同时只能删除自己的文件。
       管理文件sticky权限
          chmod  o+|- t   file .....
         展示在其他用户的执行权限位,如果本来有执行权限,显示小写t,否则显示大写T
         管理特殊权限的另一方式(8进制数)
         suid     guid      sticky   0--7
             0        0            0
         基于八进制方式赋权时,可于默认的三位八进制数字左侧再加一位八进制数字
         如:chmod   1777
 
 facl      file  access control  lists
          文件的额外赋权机制:
               在原来的u  g  o 之外,另一层让普通用户能控制赋权给另外的用户或组的赋权机制
           getfacl   
                  getfacl   file....
            setfacl
                  赋权给用户:
                         setfacl  -m  u:USERNAME:MODE   file....
                         如:setfacl  -m  u:fedora:rw  test.txt    单独给fedora用户赋予读写权限
                  赋权给组:
                          setfacl   -m  g:GROUPNAME:MODE  file.....
                   撤销赋权:
                          setfacl   -x   u:USERNAME   file
                          setfacl   -x    g:GROUPNAME   file
         增加acl后权限上下文查找顺序修改为:属主--ACL用户 ---属组---ACL组---others
         基于优先级ACL甚至可以把原来用户有的权限去除,如 setfacl -m u:fedora:---   test.txt ,单独把用户fedora权限全部去除

chattr  命令   ,用来改变文件属性
8种模式
i   不得任意更改文件或目录
a   让文件或目录仅供追加(append)用途
b   不更新文件或目录的最后存取时间
c     将文件或目录压缩后存放
d     将文件或目录排除在倾倒操作之外
s      保密性删除文件或目录
S      即时更新文件或目录
u      预防意外删除

选项
-R   递归处理
-v    设置文件或目录版本
-V     显示执行过程
 +     开启文件或目录的该项属性
  -     关闭文件或目录的该项属性
  =     指定文件或目录的该项属性
如:chattr +i  /etc/fstab    rm 、mv、rename等命令都提示无权限
      chattr  +a  /etc/fstab     让该文件只能往里追加内容,不能删除。

date 命令
date  +%Y   四位年份
date  +%y    两位年份
date  +%m   月份    +%h   中文月份
date  +%d     日
date  +%H    小时
date  +%M    分钟
date  +%S    秒
date  +%s     从1970到现在的秒数 ,一个时间戳
date  -d  @100  根据时间戳反推时间   100是时间戳
[root@localhost ~]# date +%F
2018-06-07

[root@localhost ~]# date +%T
19:16:31

[root@localhost ~]# date +"%Y-%m-%d %H:%M:%S"2018-06-07 19:19:06
[root@localhost ~]# date +%w    星期四
4
[root@localhost ~]# date +%W   今年第几周
23
[root@localhost ~]# echo "365/7" |bc  
52
一年52周,bc是内置计数器
date -d "-1 day" "+%F %T"   一天前,昨天
date -d "+1 day" "+%F %T"   一天后,明天
day 可以换成month、year、week、hour、min、sec


if  (($a>3)); then echo ok; fi
if  (($a>3)); then echo ok; else echo no; fi
if [ $a -lt 10 ]&&[ $a -gt 1 ];then echo ok;fi
if [ $a -lt 10 -a $a -gt 1 ];then echo ok;fi

[root@localhost tmp]# [ -d log.sh ]&& echo "log.sh is exist"
-d 是否目录,-z 表示值是否为空 ,-f  是否文件,-e 是否存在,-r是否可读 , -x  是否可执行 , -w 是否可写

if ls /tmp/sdfwefoiwef > /dev/null 2>&1;then echo ok; else echo no;fi

脚本中可以使用exec 来指定脚本中后面命令所有输出的位置

shell 中脚本最后一行有时候会出现exit 0  或 exit  1的写法,主要是要告诉脚本执行者是否成功执行

* * * * *   cd /tmp/bin;  /bin/bash  test.sh   任务计划
df -h |awk -F '[  %]+'  '{print $5}' 
-F后面可以指定多个分割符,中括号里面是空格或%,+号是正则表达式,表示至少一个

!-1   执行history中倒数第1条命令,也就是再次执行上一条命令
! $     传递上一条命令的执行参数供本次命令使用
!command:4   获取command命令第4个参数
!*   获取命令所有的参数
!关键字    通过关键字执行上一条命令
参考:https://linux.cn/article-5608-1.html

程序控制
 选择执行:
        if  判断条件; then