linux基础学习三
正则表达式基础正则. 匹配任意一个字符* 匹配前面字符0次或多次^ 匹配行首$ 匹配行尾[] 匹配括号内任意一个字符[^] 匹配不在括号里面的字符\ 转义符\ 匹配0次或1次.* 任意多次\ 一个以上^$ 空行^[[:space:]]*$ 空白行扩展正则 至少1次0次或者1次| 或者() 分组{n} 正好n次{n,} 至少n次{n,m} n~m次touch *.txt 刷新现有文件touchtouchgrep error test.txt 包含error的行grep 2026 test.txt 日期\. 表示点. 不加\会以为是正则表达式 [.] 里面的. 就是点grep go\{4,\}le test.txt 匹配 go 后面跟 4 个 o 或 5 个 o最后是 le 的行grep go\{4\}le 必须出现正好4次grep go\{4,7\} 出现4~7次grep go\{4,\} 出现4次及以上Shell命令bash -n shell.sh 检查语法错误bash -x shell.sh 调试模式跟踪每一行执行脚本错误常见方式语法错误会导致后续的命令不就行执行乐意用bash -n 检查结果命令错误默认后续下的命令还会继续执行可以用bash -x进行观察逻辑错误命令没问题只是执行的结果与预期不符只能用bash -x 进行观察变量namehostnameecho ${name} 显示变量执行结果 也可以echo $namecurl -s https://www.baidu.com 访问百度首页把百度的网页源代码全部输出到屏幕上numsseq 10echo $nums 显示 横排 1 2 3 4 5 6 7 8 9 10echo $nums 保持原有命令格式 显示竖排 1 2 3 4 5 6 7 8 9 10echo $nums 单引号 结果会显示$nums 当成字符串set 可以查看所有变量export 可以查看所有环境变量环境变量子进程可以继承父进程的expot name张三bashecho $name 进入子进程就可以看到父进程创建的环境变量namecat /proc/1235/environ 可以查看某个进程的环境变量只读变量readonly age18位置变量位置变量在bsh shell中内置的变量在脚本代码中调用通过命令行传递给脚本的参数$1 ,$2 …… 对应第一个第二个等参数$0 命令本身包括路径$* 传递给脚本的所有参数全部参数合并为一个字符串$ 传递给脚本的所有参数没给参数为独立字符串$# 传递给脚本的参数的个数bash test.sh a,b,c a b c 就是给脚本传递的参数1 2 3alias rm/data/test.sh alias 给一个长命令起一个短名字rm.sh: 练习脚本WARNING_COLORecho -e \E[1;33mEND\E[0mDIR/tmp/date %F_%H-%M-%Smkdir $DIRmv $* $DIR${WARNING_COLOR}Move $* to $DIR $END状态码在命令中可以用exit 100来指定状态码echo $? 可以查看状态码set -e 命令执行出错立即终止脚本set -u : 在脚本命令中 出现一个没有设置的变量时显示错误信息并退出脚本set -- 重置脚本里面的参数unset $age :删除变量printf输出格式%s 表示字符串%s\n 表示字符串与字符串之间用换行符隔开%03d 表示三位数数字数位不够的用空格填补一般默认右对齐所以空格往前补%.2f 表示两位数的浮点数- %后面加上- 表示左对齐%4s %5s\n 1 2 3 4 默认右对齐(%s) 返回的值 用() 框起来算数运算let z$x$y echo $z 返回x和y 的和z$[x*y] echo $z 返回x和y 的积z$((xy)) echo $z 返回x和y 的和((zx*y)) echo $z 返回x和y 的乘积异或x10y20;x$[x^y];y$[x^y];x$[x^y] 交换x y 的值短路与 x y 如何x为假 y命令将不执行短路或 ||x || y 如果x为真 y命令将不执行{ who;hostname; }带空格{后面必须加空格把多个命令打包成一个整体执行所有命令共用同一个输入 / 输出条件测试命令test [options] file [ options file ] 里面的命令前要加空格echo $? 查看上面命令是否正确 1为错 0为正确-a 判定file 文件存不存在-e 判定file文件 存不存在-z 判定file字符串是否为空空为真-n 判定字符串是否为不空不空为真 两边有空格 是比较两侧字符串是否相同! 比较两侧字符串是否不同-eq 两侧数值是否相等-ge 大于等于-ne 不等于-lt 小于-gt 大于-le 小于等于-a 并且的意思-o 或者的意思例子[ whoami root -a ! -e /data/dir ] mkdir /data/dir || echo 不成功表示 当前用户如果是root 并且 不存在/data/dir 目录 则创建dir目录否则输出不成功cmd1 cmd2 || cmd3 如果cmd1 为真 则执行cmd2 否则执行cmd3[[表达式]] 专门支持正则表达式 前后必须留空格~ 正则匹配符 意思是左边的字符串匹配右边的正则规则() 和{} 都可以将多个命令组合在一起批量执行(list) 会开启子shell 并且list中变量赋值以及内部命令执行会将不再影响后续的环境{list} 不会开启子shell 在当前shell中运行 会影响当前shell环境例子namewang;(nameliu;echo $name);echo $name 结果显示liu wangnamewang;(nameliu;echo $name);echo $name 结果显示liu liupstree -p 以树形结构显示当前系统所有进程并且显示每个进程的 PID进程号echo $BASHPID 输出当前这个 bash 终端自己的 PID进程号脚本练习[ $# -eq 0] || { echo userage: $0 IP ;exit; }ping -c1 -w1 s1 /dev/null echo $1 is up || echo $1 is down#磁盘控件和inode号的检查版本WARNING80SPACE_USED df | grep ^/dev/sd |grep -oE [0-9]%|tr -d %|sort -nr |head -1INODE_USEDdf -i |grep ^/dev/sd |grep -oE [0-9]%|tr -d %|sort -nr |head -1read 用法读取用户在键盘上输入的内容存到变量里#石头剪刀布read -p 石头-0 剪刀-1 布-2 请出拳 choose #-p ...→ 显示提示语choose 是变量[[ ! $choose ~ ^[0-9]$ ]] { echo 请选择正确的出拳提示!;exit; };[ $choose -eq 0 ] { echo 你选择是石头 ;exit; }[ $choose -eq 1 ] { echo 你选择是剪刀 ;exit; }[ $choose -eq 2 ] { echo 你选择是布 ;exit; }echo 请选择正确的出拳提示;exit;read -p 提示语句 aread -s -p 输入密码 pass -s表示隐藏输入密码专用read -n 1 -p 请输入一个字符 c -n 数字限制输入字符的长度read -t 5 -p xxx num -t 设置超时时间. 或者source 都可以让配置在当前状态下生效vim 编辑器多行复制 esc V 选中所有行点击y 找到目标位置点击p单行复制 escyyp 将目标行 复制到下一行流程控制条件选择#if else 版本 猜拳read -p 石头-0 剪刀-1 布-2 请出拳 chooseif [[ ! $choose ~ ^[0-9]$ ]] ;thenecho 请选择正确的出拳提示!exitelif [ $choose -eq 0 ] ;thenecho 你选择是石头exitelif [ $choose -eq 1 ] ;thenecho 你选择是剪刀exitelif [ $choose -eq 2 ] ;thenecho 你选择是布exitelseecho 请选择正确的出拳提示;fi#case 用法 石头剪刀布result$[RANDOM%3]read -p 石头-0 剪刀-1 布-2 请出拳 choosecase $choose in0)choose石头;;1)choose剪刀;;2)choose布;;*)echo 请输入正确的数字exit;;esaccase $result in0)result石头;;1)result剪刀;;2)result布;;esacif [ $choose 石头 -a $result 布 -o $choose 剪刀 -a $result 石头 -o $choose 布 -a $result 剪刀 ]; thenecho 泥塑了echo 机器人出的是$resultecho 你出的是$chooseexitelif [ $result $choose ];thenecho 平局echo 机器人出的是: $resultecho 你出的是$chooseexitelseecho 你赢了echo 机器人出的是: $resultecho 你出的是$chooseexitfifor循环for j in {1..6};dofor i in {1..6} ;doecho -e \E[5;1;$[RANDOM%731]m*\E[0m\cdoneecho #可以尝试一下去掉echo 的返回结果看一下两者的区别done或者for j in {1..6};dofor i in seq $j ;doecho -e \E[1;$[RANDOM%731]m*\E[0m\cdoneechodonefor循环另一种用法for (( i1;i100;i));dolet sumi;doneecho sum$sum批量闯将用户并随即设置密码#设置密码for i in{1..10};douseradd user$i #useradd 新建用户PASScat /dev/urandom |tr -dc [:alnum:] |head -c12# tr -dc [:alnmu:] 删除除了字母加数字以外的字符echo $PASS |passwd --stdin user$i /dev/null#--stdin 从管道 / 标准输入读取密码不用交互式输入echo user$i:$PASS /data/user.logecho user$i is createddone将指定目录下面的文件所有文件的后缀改名为bak后缀#将指定目录下面的所有文件后缀改为bakDIR/data/testcd $DIR || { echo 无法进入$DIR;exit; }for file in * ;do[[ $file ~ \.bak ]] continuePREecho $file|grep -Eo .*\.mv $file ${PRE}bakdone将某个目录下面的YYYY_MM_DD 格式的目录转化成YYYY_MM/DD 目录并将对应目录下面的文件移动过去#创建对应的YYYY_MM_DD目录环境PDIR/data/testfor i in {1..365} ;doDIRdate -d -$i day %F #date 设置时间的命令 -d 字符串 自定义计算时间 -$i day -表示往前推 $i循环变脸 day 天 %F 是日期格式化符号mkdir -pv $PDIR/$DIRcd $PDIR/$DIRfor j in {1..10};dotouch $RANDOM.logdonedone#解决方案如下DIR/data/testcd $DIR || { echo 无法进入 $DIR;exit 1;}for subdir in * ;doYYYY_MMecho $subdir|cut -d- -f1,2DOecho $subdir|cut -d- -f3[ -d $YYYY_MM/$DO ] || mkdir -p $YYYY_MM/$DO /dev/nullmv $subdir/* $YYYY_MM/$DOdone