bash的初始化
bask环境变量文件的加载
/etc/profile
/ect/bashrc
~/.profile
~/.bask_login
~/.bash_profile
~/.bashrc
~/.bash_logout
1:正确输出
2:错误输出
0:正确输入
&:正确和错误输出
&&表示前面的语句正确,才会执行后面的语句
ls / && echo 'success'
||表示前面的语句失败,才会执行后面的语句
ls /abc || echo 'filed'
;表示两个语句并列执行
ls /; echo 'success'
tty查看当前终端
nohup 将本次执行的命令延续到下一个终端开启
nohub sleep 5000
执行方式
bash bash.sh #在子shell中执行
./bash.sh #在子shell中执行
. bash.sh #在当前shell中执行
source .bash.sh #在当前shell中执行
-vx 执行过程
--------------------
#当不确定sh bash在什么位置时,可以使用env去查找位置
#!/bin/env bash/python/except
通配符
字符 | 含义 | 实例 |
---|---|---|
* | 匹配0个或多个任 意字符 | a*b ,a与b之间可以有任意长度的字符 ,也可以没有。例如: aabcb ,ab ,azxcb... |
? | 匹配一个任意字符 | a?b ,a与b之间必须但也只能存在一个字符 ,该字符可以是任 意字符。例如:aab ,abb ,acb... |
[list] | 匹配list中的任意 单个字符 | a[xyz]b ,a与b之间必须但也只能存在一个字符 ,该字符只能 是x或y或z。例如:axb ,ayb ,azb |
[!list] | 匹配除list中的任 意单个字符 | a[!a-z]b ,a与b之间必须但也只能存在一个字符 ,该字符不能 是小写字母。例如:aAb ,a0b... |
[c1-c2] | 匹配c1-c2间的任 意单个字符 | a[0-1]b ,a与b之间必须但也只能存在一个字符 ,该字符只能 是数字。例如:a0b ,a1b... |
{string1,string2,...} | 匹配string1、 string2等中的一 个字符串 | a{abc,xyz,opq}b ,a与b之间必须但也只能存在一个字符串, 字符串只能是abc或xyz或opq。例如:aabcb ,axyzb , aopqb... |
shell脚本调试
bash/sh [参数] 文件名.sh
-n 不要执行script 仅查询语法文件
-v 在执行script之前,先将script的内容输出到屏幕上
-x 将使用的脚本的内容输出到屏幕上
Shell脚本的执行方式
exit 退出执行脚本
脚本格式要求
1、脚本以 #!/bin/bash 开头
2、脚本需要有可执行权限
3、stty erase '^H' 在脚本的最开始加入这句话,退格键即可识别
变量
Linux Shell中的变量分为系统变量和用户自定义变量
系统变量:$HOME $PWD $SHELL $USER 等等
显示当前shell中所有变量:set
在父SHELL中定义的变量,在子SHELL中更改,是不会修改到父SHELL的值,只在当前SHELL生效
shell变量的定义
定义变量:变量=值
A=100
撤销变量:unset 变量
unset A
声明静态变量:readonly变量 注意:静态变量不能unset
readonly A = 100
定义变量的规则
1、变量名称可以由字母、数字和下划线组成,但是不能以数字开头
2、等号两侧不能有空格
3、变量名称一般习惯为大写
将命令的返回值赋给变量
A=`date` #运行里面的命令,并把结果返回给变量A
A=$(date) #两个等价
设置环境变量
环境变量又叫全局变量
export 变量名=变量值 (将shell变量输出为环境变量)
source 配置文件 (让修改后的配置信息立即生效)
echo $变量名 (查询环境变量的值)
注意:设置完环境变量后,需要让其生效则使用 source /etc/profile
# 单行注释
<<!
多行注释
!
位置参数变量
$n (功能描述:n为数字,¥0代表命令本身,¥1-$9代表第一个到第九个参数,10以上的参数需要使用大括号包含,例如 $(10))
$* 这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
$@ 这个变量也代表命令行中所有的参数,不过$@把每个参数区分对的
$# 这个变量代表命令行中所有参数的个数
$$ 表示当前进程的PID
预定义变量
就是事先已经定义好的变量,可以直接在shell脚本中使用
$$ 当前进程的进程号(PID)
$! 后台运行的最后一个进程的进程号(PID)
$? 最后一次执行的命令的返回状态,如果这个变量的值为0,则证明上一个命令正确执行,如果这个变量的值非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确
$0 表示该脚本本身
read读取变量
read variable
read -p "tips" variable #有提示
read -t number -p "tips" variable #限制多少秒后不能输入
read -n number -p "tips" variable #只读取多少个字符
定义引用变量
" " 弱引用 自动转换变量名,输出变量名的值
' ' 强引用 不会转换变量名 原样输出内容
局部变量
local 变量名
查找
url=www.sina.com.cn
echo $url
echo "获取变量值的长度: ${#url}"
echo "从前往后,最短匹配: ${url#*w}"
echo "从前往后,最长匹配 贪婪匹配:${url##*w}"
echo "从后往前,最短匹配: ${url%w*}"
echo "从后往前,最长匹配 贪婪匹配: ${url%%.*}"
索引和切片
url=www.sina.com.cn
echo "${url:0:5}" #从第一位开始,截取5位
echo "${url:5}" #从第五位开始,截取到最后一位
内容替换
url=www.sina.com.cn
echo ${url/sina/qzsec} #将sina替换为qzsec
echo ${url/w//W} #将所有w替换为W 贪婪匹配
url=www.sina.com.cn
echo ${url-abc} #不可替换
echo ${url+abc} #可替换
echo ${url?abc} #不可替换
echo ${url=abc} #不可替换
echo ${url:-abc} #不可替换
echo ${ur:+abc} #不可替换
echo ${url:=abc} #不可替换
abc=''
echo ${abc-abc} #不可替换
echo ${abc+abc}: #可替换
echo ${abc?abc}: #不可替换
echo ${abc=abc}: #不可替换
echo ${abc:-abc}: #可替换
echo ${abc:+abc}: #不可替换
echo ${abc:=abc}: #可替换
字符串变量养成习惯,加上双引号
运算符
基本语法
<<!
1. $((运算式)) 或者 $[运算式] 或者 expr m + n 或者 let variable=m+n; echo variable
2. 注意expr运算符要有空格
3. expr m - n
4. expr \*,/,% 乘,除,取余
!
#!/bin/bash
echo "(2+3)*4 = $[$[2+3]*4]"
echo $1+$2 = $[$1 + $2]
A=$[$[10+100]*200]
echo A=$A
let sum=1=1;echo $sum
#小数运算
#使用bc
yum install -y bc
echo "scale=2;2.2/4"|bc #scale保留小数 位数不够0来凑
#使用awk
echo "1/2"| awk '{printf("%.2f",1/2)}' %.2f保留两位小数,位数不够0来凑
条件判断
[ condition ] (注意condition前后要有空格)
#非空返回true,可以使用$?验证 (0为true,>1为false)
#!/bin/bash
[ -d /root/shcode/aa ] && echo "存在"
常用的判断条件
1. = 字符串比较
2. 两个整数的比较
-lt 小于
-le 小于等于
-eq 等于
-gt 大于
-ge 大于等于
-ne 不等于
3. 按照文件权限进行判断
-r 有读的权限
-w 有写的权限
-x 有执行的权限
4. 按照文件类型进行判断
-f 文件存在并且是一个常规的文件
-e 文件存在
-d 文件存在并且是一个目录
-L 是不是一个快捷方式
5. 判断是否存在
-n 长度不是0 -n "$1"
-z 长度是0
test 常用于比较
a=1
test $a = 1
echo $?
0 true 1 false
[ ] 也用于比较
[ $a = 1 ]
echo $?
0 true 1 false
流程控制
(()) 数值比较,运算 C语言
[[]] 条件测试,支持正则
$(()) 整数运算
$[] 整数运算
$() 命令替换 shell会先执行括号的cmd,然后将结果作为变量进行替换,替换只能替换标准输出,错误输出不能替换。
${} Shell中变量的原形,用于限定变量名称的范围,并且支持通配符
[] 条件测试
() 子shell中执行
{} 在当前 shell 执行
# ()是重新开一个子shell然后执行,而{}则是在当前shell里执行。
# ()最后一个命令可以不用分号,{}最后一个命令要用分号。
# ()里第一个命令和左边括号不必有空格,而{}第一个命令和左括号之间必须有一个空格。
# ()和{}里的某个命令的重定向只影响该命令, 而括号外的重定向则影响到括号里的所有命令。
# {}会改变当前shell的值
例:
var=test
echo $var ====>test
(var=notest;echo $var)===>notest
echo $var ====>test
{ var=notest;echo $var;} ====>notest
echo $var ====> notest
if语句
if [ 条件判断 ]
then
....
fi
或者
if [ 条件判断 ]
then
...
elif [ 条件判断 ]
then
...
else
...
fi
注意事项: [ 条件判断 ],中括号和条件判断直接必须要有空格
#多个条件进行判断[单分支] -a 逻辑与 -o 逻辑或
if [ $a = $b -a $c = $d ]; then 程序; fi
if [ $a = $b -o $c = $d ]; then 程序; fi
case语句
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
.....
*)
如果变量的值都不是以上的值,则支持该程序
;;
esac
#最后一个可以不加;;
for循环
#基本语法1
for 变量 in 值1 值2 值3...
do
程序
done
#基本语法2
for ((初始值;循环控制条件;变量变化))
do
程序
done
#打印命令行输入的参数[这里可以看出$* 和 $@的区别 ]
for I in "$*"
do
echo "num is $I"
done
echo "================================"
for J in "$@"
do
echo "num hh is $J"
done
echo "=================================="
# 从1加到100的值输出显示
SUM=0
for(( I=1; I<=100; I++ ))
do
SUM=$[$SUM + $I]
done
echo $SUM
#使用序列
for $i in {1..100}; do sum=$[$sum+$i]; done echo $sum
#for循环后如果不跟参数,则默认取全部参数
for i in
do
let sum=$sum+$i
done
echo $sum
./test.sh 1 2 3 4 #10
while循环
while [ 条件判断 ]
do
程序
done
#!/bin/bash
#判断用户输入的是不是数字
read -p "请输入一个数字:" num
while true
do
if [[ $num =~ ^[0-9]+$ ]];then
break
else
read -p "请重新输入一个数字:" num
fi
done
echo "你输入的数字是:$num"
until循环
until 条件
do
程序
done
#当为false的时候执行
while ping -c1 -W1 192.168.98.199
do
sleep 1
done
echo "this ip is up."
read读取控制台输入
read (选项)(参数)
选项
-p 指定读取值的时候的提示符
-t 指定读取值时等待的时间(秒),如果没有在指定的时间内输入,就不在等待了
参数
变量 指定读取值的变量名
#!/bin/bash
read -p "请输入num的值:" NUM
echo "这是我输入的值: $NUM"
read -p "请输入num2的值:" NUM2
echo "这是我输入的num2的值:$NUM2"
echo $NUM+$NUM2= $[$NUM+$NUM2]
数组
#普通索引数组
arr=(a b c d) #索引从0开始
${arr[0]}
#自定义索引数组[关联数组]
declare -A arr=([name]=a [skill]=python) #-A 关联数组 -a 普通数组
${arr[name]}
#查看数组所有的值
${arr[@]}
#查看数组所有的索引
${!arr[@]}
#查看数组元素个数
${#arr[@]}
#遍历数组
${arr[@]:1} #从第一个元素开始遍历
${arr[@]:1:2} #从第一个元素开始遍历,访问两个元素
#!/bin/bash
while read line
do
hosts[++i]=$line
done </etc/hosts
echo "hosts first: ${hosts[1]}"
for i in ${!hosts[@]}
do
echo "$i : ${hosts[i]} "
done
函数
系统函数
basename基本语法
功能:返回完整路径最后 / 的部分,常用于获取文件名
basename [pathname] [suffix]
basename [string] [suffix] 描述:basename命令会删除掉所有的前缀包括最后一个("/")字符,然后将字符串显示出来
suffix:为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉
dirname基本语法
功能:返回完整路径最后 / 的前面的部分,常用语返回路径部分
dirname 文件绝对路径 描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回生剩下的路径(目录部分)
自定义函数
[ function ] funname[()]
{
Action;
[return init;]
}
调用直接写函数名 funname [值]
#!/bin/bash
read -p "请输入num的值:" NUM
read -p "请输入num2的值:" NUM2
function getSum(){
echo $[$NUM+$NUM2];
}
getSum $NUM $NUM2
shift
位置变量往前移
#综合案例
<<!
每天凌晨2:30备份数据库到/data/backup/db
备份开始和备份结束能够给出相应的提示信息
备份后的文件要求以及备份的时间为文件名,并打包为.tar.gz的形式
在备份的同时,检查是否有10天前备份的数据库文件,如果有则删除
!
#!/bin/bash
正则表达式
grep:匹配不包含特殊字符
cat /etc/password | grep password #匹配包含password的内容
^:匹配一行的开头
cat /etc/password | grep ^abc #匹配以abc开头的内容
$:匹配一行的结束
cat /etc/password | grep abc$ #匹配以abc结尾的内容
.:匹配任意一个字符
cat /etc/password | grep r..t #匹配包含r和t并且中间带两个任意字符的内容
*:匹配上一个字符多次
cat /etc/password | grep r*t #匹配包含r出现多次并且后面跟着t的内容
.*:匹配任意多个字符
[]:匹配字符区间的任意字符
[0,1]:匹配0或者1
[0-9]:匹配0到9的一个数字
[0-9]*:匹配任意长度的数字字符串
[a-c,f-g]:匹配a到c或f到g直接的任意字符
\:进行转义 #转义要加单引号
cat backup.sh | grep '\$'
{}:匹配指定次数或多次 -E 支持扩展 -E
echo "13888888888" | grep -E ^1[3578][0-9]{9}$
#匹配IP
egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-ens33
\:表示转义
egrep === grep -E
文本处理工具
awk
文本截取
cut [选项参数] filename
-f:列号,提取第几列
-d:分隔符,按照指定分隔符分割列,默认制表符"\t"
-c:按字符进行切割后加n表示第几列
cut -d "分隔符" -f 第几列 文件路径
cut -d " " -f 1 cut.txt
cat /etc/passwd | grep bash$ | cut -d ":" -f 1,6,9,11- #11- 表示从11截取到最后
文本分析
awk [选项参数] '/pattern/{action} /pattern2/{action2}...' filename
pattern:表示awk在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
-F:指定输入文件分隔符 #默认按照空格切分
-v:赋予一个用户定义变量
cat /etc/passwd | awk -F ":" '/^root/ {print $7}'
#获取以root开头的内容,并以:分割开始,打印输出第七个
cat /etc/passwd | awk -F ":" '/^root/ {print $7","$1}'
cat /etc/passwd | awk -F ":" 'BEGIN{print "start the etc/passwd file"} /^root/{print $1","$7} END{print "end the file"}'
cat /etc/passwd | awk -F ":" -v i=2 '{print $3+i}'
BEGIN 在所哟8u数据读取行之前执行
END 在所有数据执行之后执行
内置变量
FILENAME 文件名
NR 已读的记录数(行号) 所在行号 所有文件的行数累加
awk -F":" '{print NR,$0}' passwd /etc/hosts
FNR 已读的记录数(行号) 所在行号 当前文件的行号 每个文件的行号是独立的
awk -F":" '{print FNR,$0}' passwd /etc/hosts
NF 记录的域的个数(切割后,列的个数) 有多少列
$NF 最后一个字段(列)内容
$0 当前记录的内容
awk -F ":" '{print "当前文件名为:"FILENAME "当前行号:"NR "列数为:"NF $1","$7}' /etc/passwd
ifconfig | awk '/^$/ {print NR} #获取空行
ifconfig | awk '/netmask/ {print $1,$2}' #获取IP
%s 字符类型
%d 数值类型
%f 浮点类型
- 表示左对齐 默认是右对齐
awk -F: '{printf "%-15s %-10s % -15s\n",$1,$2,$3}' /etc/passwd
sed
sed
#可以对输入输出文件的行进行筛选、替换、修改、打印等操作,并且可以将修改结果保存到源文件中
set [选项] '命令' file
-n:去掉缺省输出,缺省输出中包含sed命令读取的所有行,除替换和删除操作外一般都会加上该参数
-i:将修改操作应用到源文件上,否则操作更改的内容只是显示到屏幕
-e:允许对一行进行多次编辑
-r:使用扩展的正则表达式
-f:从文件中读取sed操作命令
-----
d:删除行
sed -r '3{d}' 1.txt
p:输出/打印行
r:读取文件
s:替换字符串
a\:在当前行后插入
i\:在当前行前插入
c\:修改当前行
$p:表示最后一行
#打印
-
#打印1-3行
sed -n '1,3p' /etc/passwd
#打印最后一行
sed -n '$p' /etc/passwd
#打印含有字符串swap的行
sed -n '/swap/p' /etc/fstab
#打印匹配字符串nginx开始到最后一行
sed -n '/nginx/,$p' /etc/passwd
#打印注释行
sed -n '/^ *#/p' /etc/fstab
#打印非注释行
sed -n '/^[^ *#]/p' /etc/fstab
#打印不含有swap的行
sed -n '/swap/!p' /etc/fstab
#打印匹配有nginx的行号
sed -n '/nginx/=' /etc/group
#替换文本
-
sed [address[,address]] 's/regexp/replacement/[g p w r]'
g:缺省情况下,只替换每行中第一次出现的样式,使用g选项进行每行中所有的匹配样式
p:在sed命令加上-n参数时,被替换的行不会输出到屏幕,加上p选项可以只打印被替换的行到标准输出
w file:只将替换过的行输出到一个文件file
r file:将文件file的内容添加到匹配到的行后
模式空间
使用G,g将暂存空间的内容放回模式空间 存放的默认都是空行
g是覆盖 G是追加
暂存空间
使用H,h可以将模式空间的内容放入暂存空间
h是覆盖 H是追加
x:将暂存空间和模式空间的内容互换
#将第一行复制到最后一行
sed -r '1h;$G' passwd
#移动第一行到最后一行
sed -r '1{h;d};G' passwd
#将所有内容替换成第一行
sed -r '1h;2,$g' passwd
#将第一二三行复制到最后一行
sed -r '1h;2,3H;G' passwd
!反向选择
sed -r '1d' passwd #删除第一行
sed -r '1!d' passwd #删除除第一行外的所有行
#替换输出每一行中第一次出现的c33替换为d33
sed 's/c33/d33/' 2.sh | grep d33
#替换每一行第二次出现的c33替换为d33
sed 's/c33/d33/2' 2.sh | grep d33
#替换输出行中所有出现c33为d33
sed 's/c33/d33/g' 2.sh
#替换行中出现的c33为d33 并将被替换的行写入到2.txt文件中
sed 's/c33/d33/g w 2.txt' 2.sh
#匹配替换第0行到第一行匹配到c33为d33
sed '0,/c33/ s/c33/d33/g' 2.sh
#匹配行中所有的c33并在后面加上d33
sed 's/c33/&d33/g' 2.sh
#替换文件末尾的空格
sed -i 's/ *$//' 2.sh
#删除匹配字符串east的行
sed '/east/d' file.txt
#删除1到3行
sed '1,3d' file.txt
#删除从root开始到字符串tcpdump结束的行
sed '/root/,/tcpdump/d' /etc/passwd
#禁用seLinux
sed -ri 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
sed -ri '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config
sed -r '/^root/,5d' passwd #删除到第五行
sed -r '/^root/,+5d' passwd #再删除5行
#删除以#开始的行
sed -r '/^[ \t]*#/d' 1.txt
#删除以//开始的行
sed -r '\#^[ \t]*//#d' 1.txt # #是任意的
sed -r '/^[ \t]*\/\//d' test.txt
#删除无内容空行
sed -r '/^[ \t]*$/d' 1.txt
#删除注释行以及空行
sed -ri '/^[ \t]*#/d;/^[ \t]*$/d' 1.txt #0或多个空格删掉,0或多个tab删掉
sed -ri '/^[ \t]*#|^[ \t]*$/d' 1.txt #将0或多个空格或0或多个tab删掉
sed -ri '/^[ \t]*($|#)/d' 1.txt #将0或多个空格或tab删掉
#在最后一行添加内容
sed -ri '$a\chroot_local_user=YES' 1.txt
#给1到5行改为注释
sed -r '1,5s/^[ \t]*#*/#/' 1.txt #将1到5行添加#,并且带有0或多个空格或tab的#替换成#
sed -r '1,5s/^[ \t#]*/#/' 1.txt #将空格或tab或#替换成#
#使用变量
sed -r '$a'"$var1" 1.txt #$ 表示最后一行 a 表示在当前行后插入
#内容倒转
sed -r '1!G;$!h; $!d' 1.txt
#在最后一个字符前面加YYY
sed -r 's/(.*)(.)/\1YYYY\2/' passwd
#在第二个字符前面加TTT
sed -r 's/(.)(.)(.)*/\1YYYY\2\3/' passwd
#最多9个小括号
#删除下一行
sed -r '/adm/{n;d}' passwd
#查询当前元素的下一行,并替换内容
sed -r '/adm/{n;s/sbin/uuuuuuuuuuu/}' passwd
#替换以SELINUX的整行内容
sed '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config
#替换查找到的内容
sed 's/abc/bcd/' text.txt
#将2到4行设置为注释
sed -r '2,4s/^/#/' test.txt
sed -r '2,4s/(.*)/#\1/' test.txt #\1表前面所查询到的内容
sed -r '2,4s/(.*)/#&/' test.txt #&表前面所查询到的内容
#将所有内容替换为以#开头的注释行
sed -r '1,$s/^[ \t]*(#|\/\/)*/#/' test.txt
#内容翻转
sed -r '1!G;$!h; $!d' test.txt
切片
variable:start:length
except
#!/usr/bin/expect
set ip 192.168.98.124
set user root
set password 123456
set timeout 5
#创建一个会话
spawn ssh $user@$ip
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$password\r" };
}
interact
-------------------------------------
#使用位置参数
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
set timeout 5
#创建一个会话
spawn ssh $user@$ip
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$password\r" };
}
interact
--------------------------------------
#不停留在bash里面,执行指令后,返回
#!/usr/bin/expect
set ip 192.168.98.124
set user root
set password 123456
set timeout 5
spawn ssh $user@$ip
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$password\r" };
}
#interact
expect "#"
send "pwd\r"
send "exit\r"
expect EOF
---------------------------------------
#scp传文件
#!/usr/bin/expect
set ip 192.168.98.124
set user root
set password 123456
set timeout 5
spawn scp -r /opt/shell/ip.txt $user@$ip:/tmp
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$password\r" };
}
#interact
expect EOF
其他
#echo输出颜色文字
echo -e "\e[1;30-37m文本\e[0m"
#echo输出带背景颜色的文字
echo -e "\e[1;40-47m文本\e[0m"
echo -n 不换行
command -v xxx #判断是否是命令,如果是返回0,否则返回1
command -v /bin/passwd;echo $? #1
command -v /bin/ls;echo $? #0
#如果想判断语句里面什么都不做可以加":"
if date;then
:
else
echo
fi
updatime 内存负载情况
fdisk -l 磁盘分区
#远程修改密码
ssh ip "echo password | passwd --stdin root"
#按换行分割
IFS=$'\n'
#指定一段代码按\n分割,其余的按默认分割
OLD_IFS=$IFS
IFS=$'\n'
for line in `cat /etc/hosts`
do
....
done
IFS=$OLD_IFS
反引号引用的相当于在子shell中执行
grep -c 统计是否有找到,找到返回数量 没找到返回0
unset array[*] #清空数组
案例
1、批量创建用户
#!/bin/bash
#=======================================
#useradd =
#v1.0 by qzsec 24/7/2023 =
#=======================================
#判断是不是输入的数字
read -p "Please input number:" num
if [[ ! "$num" =~ ^[0-9]+$ ]];then
echo "error number!"
exit
fi
#判断是不是有输入内容
read -p "Please input prefix:" prefix
if [ -z "$prefix" ];then
echo "prefix can't be empty!"
exit
fi
for i in $(seq $num)
do
user=$prefix$i
useradd $user
echo "123456" | passwd --stdin $user &>/dev/null
#判断是否创建成功
if [ $? -eq 0 ];then
echo "create $user success"
else
echo "create $user faild"
fi
done
2、删除修改时间超过两天的文件
find /opt/data -mtime +2 -exec rm -rf {}\;
--
find /opt/data/ -mtime +2 | xargs rm -rf