shell的学习
Posted lifei02
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell的学习相关的知识,希望对你有一定的参考价值。
shell的学习
一.简述shell:
shell在官方的定义是linux内核的外壳,提供外部与Linux内核之间交互的工具。shell是一种语言,具有跨平台移植性,有多个版本如csh,ksh,sh。个人用的最多的是bash,Linux 操作系统缺省的 shell 是Bourne Again shell,它是 Bourne shell 的扩展,简称 Bash。
查看当前使用的shell类别:
[email protected]-unknown85879:/home/zhugeling$ which sh
/bin/sh
[email protected]-unknown85879:/home/zhugeling$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Nov 13 12:01 /bin/sh -> bash
二、如何学习shell?
个人感悟:其实shell的语法跟C语言差不多,但是shell还有很多可供使用的很多强大的命令,如sed,awk,grep等,实用性更强。在学习过程中,基础语法并不是很多,但是结合正则表达是和各种命令之后,变得很灵活。个人的感觉是在理解shell的解析原理基础上要多练习,多练习,多练习!!!不然记不住那么多命令,参数等等。
三、学习shell基础语法
1、变量:
(1)shell的变量不需要特殊声明,引用的时候要在前面用$符号。
(2)变量的赋值,对空格比较敏感,如:
[[email protected] ~]# myvalue= 123
-bash: 123: command not found
[[email protected] ~]# myvalue =123
-bash: myvalue: command not found
[[email protected] ~]# myvalue=123
[[email protected] ~]# echo $myvalue
123
变量赋值时,”=”号两边不能有空格
另外引用变量时,尽量用{} 确定变量的范围,变量名不能含有内置变量(shell的特殊变量)。
双引号和单引号对变量的影响
单引号里用$引用的变量将失效:
[email protected]-unknown85879:~/tmp$ name=zhugeling
[email protected]-unknown85879:~/tmp$ echo $name
zhugeling
[email protected]-unknown85879:~/tmp$ sayhello="Hello $name"
[email protected]-unknown85879:~/tmp$ echo $sayhello
Hello zhugeling
[email protected]-unknown85879:~/tmp$ sayhello=‘Hello $name‘
[email protected]-unknown85879:~/tmp$ echo $sayhello
Hello $name
(3)shell的特殊变量:
shell有一些特殊变量,这些变量经常在脚本用回用到,有必要学会如何使用。
$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
[email protected] 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会用测试用例讲到。
$? 上个命令的退出状态,或函数的返回值。一般情况下,大部分命令执行成功会返回 0,失败返回 1。
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
测试变量:
测试示例1:输出各个内置变量的含义值
[[email protected] tmp]# cat test.sh
#!/bin/bash
a=$0
b=$2
c=$#
d=$*
e=[email protected]
f=$?
g=$$
echo $a
echo $b
echo $c
echo $d
echo $e
echo $f
echo $g
输入1,2,3参数,输出:
[[email protected] tmp]# sh test.sh 1 2 3
test.sh
2
3
1 2 3
1 2 3
0
26583
测试示例2:研究?和@的区别
[email protected]-unknown85880:~/tmp$ cat test.sh
#!/bin/bash
for var in "$*"
do
echo "* is $var"
done
for var in "[email protected]"
do
echo "@ is $var"
done
[email protected]-unknown85880:~/tmp$ sh test.sh 1 3 5 6
* is 1 3 5 6
@ is 1
@ is 3
@ is 5
@ is 6
区别:?在同一行了,而@则逐个换行了,怀疑是 $* 把所有参数当成一个变量了,我们修改脚本测试一下,加入自加变量并输出。
[email protected]-unknown85880:~/tmp$ cat test.sh
#!/bin/bash
i=0
j=0
for var in "$*"
do
echo "* is $var"
i=$((i+1))
echo "i is $i"
done
for var in "[email protected]"
do
j=$((j+1))
echo "j is $j"
echo "@ is $var"
done
[email protected]-unknown85880:~/tmp$ sh test.sh 1 3 5 6
* is 1 3 5 6
i is 1
j is 1
@ is 1
j is 2
@ is 3
j is 3
@ is 5
j is 4
@ is
可以确认他们的区别就是,当引用@和* 的使用,如果用双引号扩起来,则?是会变成一个变量值,而@则是会按空格区分多个变量,如果输入的参数 类似 “a d”,也会被当成一个变量。
(4)获取用户输入为变量赋值:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
echo -e "input your name:"
read name
echo "your name is $name !"
[email protected]-unknown85879:~$ sh test.sh
input your name:
zhugeling
your name is zhugeling !
2、数组:
shell也是一种语言,数组也是必不可少的,数组也是一种变量,组合变量。
shell的数组下标是用中括号括起来,从0开始计算第一个数组变量,声明时可以直接赋给值,用空格分隔开变量值。
数组使用示例:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
#空数组arr1
arr1=()
arr2=(1 2 3 4 5 6)
echo ${arr2[0]}
echo ${arr2[5]}
[email protected]-unknown85879:~$ sh test.sh
1
6
数组可以参与循环的使用:
for循环引用数组的时候,数组的下标用@符号,其含义可以参看前面的特殊变量说明,将@换成*也可以实现下面的效果。
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
#空数组arr1
arr1=()
arr2=(1 2 3 4 5 6)
for var in ${arr2[@]}
do
echo "i am $var !"
done
[email protected]-unknown85879:~$ sh test.sh
i am 1 !
i am 2 !
i am 3 !
i am 4 !
i am 5 !
i am 6 !
3、if判断语句:
算术比较运算符
num1 -eq num2 等于 [ 3 -eq $mynum ]
num1 -ne num2 不等于 [ 3 -ne $mynum ]
num1 -lt num2 小于 [ 3 -lt $mynum ]
num1 -le num2 小于或等于 [ 3 -le $mynum ]
num1 -gt num2 大于 [ 3 -gt $mynum ]
num1 -ge num2 大于或等于 [ 3 -ge $mynum ]
[ -z " $num" ] 等于零
= 两个字符相等
!= 两个字符不等
-n 非空串 不为空
–b 当file存在并且是块文件时返回真
-c 当file存在并且是字符文件时返回真
-d 当pathname存在并且是一个目录时返回真
-e 当pathname指定的文件或目录存在时返回真
-f 当file存在并且是正规文件时返回真
-g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
-h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
-k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
-p 当file存在并且是命令管道时返回为真
-r 当由pathname指定的文件或目录存在并且可读时返回为真
-s 当file存在文件大小大于0时返回真
-u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
-x 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
-o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真
语法:
(1)单分支:
if 判断条件;then
.......
fi
(2)双分支:
if 判断条件;then
.....
else
....
fi
(3)多分支会用到elif: 注意elif 也要带 then
例如:
if [[ "$x" -le "100" ]];then
echo "good."
elif [[ "$x" -lt "60" ]];then
echo "ok."
else
echo "Unknow argument...."
fi
常见用法:
(1)判断脚本程序中前一句的执行情况:
$? 为0则是执行成功,1则失败
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
cd /home/zhugeling
if [ $? -eq 0 ];then
echo "success"
else
echo "fail"
fi
[email protected]-unknown85879:~$ sh test.sh
success
(2)、判断用户输入的参数是否为空:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
read -p "input your name:" name
if [ ! -n "$name" ] ;then
echo "your input is null !"
else
echo "your input is $name"
fi
[email protected]-unknown85879:~$ sh test.sh
input your name:zhugeling
your input is zhugeling
[email protected]-unknown85879:~$ sh test.sh
input your name:
your input is null !
(3)、判断文件夹是否存在,判断文件是否存在:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
read -p "input your file :" file
if [ -d "$file" ]
then
echo "diretory $file found."
else
echo "diretory $file not found."
fi
if [ -f "$file" ]
then
echo "file $file found."
else
echo "file $file not found."
fi
[email protected]-unknown85879:~$ sh test.sh
input your file :tmp
diretory tmp found.
file tmp not found.
[email protected]-unknown85879:~$ sh test.sh
input your file :test.sh
diretory test.sh not found.
file test.sh found.
(4)判断字符串或数值等于,大于,小于等:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
read -p "input your number1 :" number1
read -p "input your number2 :" number2
if [ $number1 -eq $number2 ]
then
echo "$number1 等于 $number2."
elif [ $number1 -gt $number2 ]
then
echo "$number1 大于 $number2 "
else
echo "$number1 小于 $number2 "
fi
[email protected]-unknown85879:~$ sh test.sh
input your number1 :12
input your number2 :13
12 小于 13
[email protected]-unknown85879:~$ sh test.sh
input your number1 :18
input your number2 :16
18 大于 16
[email protected]-unknown85879:~$ sh test.sh
input your number1 :12
input your number2 :12
12 等于 12.
上面判断的变量值还可以是字符串,用于字符串是否与预期的一致等。
判断字符串是否相等 不能用 -eq 要用: = 或 ==号:
if [ “var"="var2“ ] ;then
….
fi
4、shell的循环
(1)for循环
语法格式:
格式1:
for 变量 in 列表值1 列表值2 ... 列表n值
do
语句1
语句2
...
语句n
done
示例:看看下面两种循环条件的写法,保证 in后面的是一组有值的变量或常量。
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
read -p "input your number1 :" number1
read -p "input your number2 :" number2
for var in $(seq $number1 $number2)
do
echo "now is $var"
done
for var in {1..3}
do
echo "now $var"
done
[email protected]-unknown85879:~$ sh test.sh
input your number1 :1
input your number2 :4
now is 1
now is 2
now is 3
now is 4
now 1
now 2
now 3
格式2:类似C语言格式
for ((初始值;判断条件;步长值))
do
语句1
语句2
...
语句n
done
示例:
#!/bin/bash
read -p "input your number1 :" number1
read -p "input your number2 :" number2
for((i=$number1;i<$number2;i++))
do
echo "now is $i"
done
[email protected]-unknown85879:~$ sh test.sh
input your number1 :1
input your number2 :3
now is 1
now is 2
(2)、while循环
格式1:
while [ $num -le $num2 ] ------两个变量之间
do
语句1
语句2
...
语句n
num =$((num+1)) ----------变量自加方式1
done
格式2:
while [ $num -le $num2 ] ------两个变量之间
do
语句1
语句2
...
语句n
num=` expr $num + 1` ---变量自加方式2
done
示例:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
read -p "input your number1 :" number1
read -p "input your number2 :" number2
i=$number1
#while [ $i -le $number2 ]
while (($i<$number2))
do
echo "now is $i"
i=$(($i+1))
done
[email protected]-unknown85879:~$ sh test.sh
input your number1 :1
input your number2 :3
now is 1
now is 2
(3)、循环的常见用处:
按文件列表循环:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
read -p "inputh your dir:" dir
for var in `ls $dir`
do
echo "file is $var"
done
[email protected]-unknown85879:~$ sh test.sh
inputh your dir:/home/zhugeling/tmp
file is test1.txt
file is test2.txt
file is test3.txt
批量创建用户或文件(这里以创建文件示例):
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
dir=/home/zhugeling/tmp
cd $dir
for var in {1..10}
do
touch filename$var
done
[email protected]-unknown85879:~$ sh test.sh
[email protected]-unknown85879:~$ cd tmp/
[email protected]-unknown85879:~/tmp$ ls
filename1 filename10 filename2 filename3 filename4 filename5 filename6 filename7 filename8 filename9
循环检测一个IP段的连通性:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
for var in {1..20}
do
ping -c2 10.83.3.$var &>/dev/null
if [ $? -eq 0 ];then
echo "10.83.3.$var is exist !"
else
echo "10.83.3.$var is not exist !"
fi
done
[email protected]-unknown85879:~$ sh test.sh
10.83.3.1 is exist !
10.83.3.2 is not exist !
10.83.3.3 is not exist !
10.83.3.4 is not exist !
10.83.3.5 is not exist !
10.83.3.6 is not exist !
10.83.3.7 is not exist !
10.83.3.8 is not exist !
10.83.3.9 is not exist !
10.83.3.10 is exist !
10.83.3.11 is exist !
10.83.3.12 is exist !
10.83.3.13 is exist !
10.83.3.14 is exist !
10.83.3.15 is exist !
10.83.3.16 is exist !
10.83.3.17 is exist !
10.83.3.18 is exist !
10.83.3.19 is exist !
10.83.3.20 is exist !
此外循环还可以用于统计数值,循环执行某些命令等用途。
5、shell的分支case
shell的分支是用case语句控制,语法如下:
case 值 in
模式1)
命令1
...
;;
模式2)
命令2
...
;;
......
esac
简单示例:
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
case $1 in
start )
echo "server is starting !"
;;
stop )
echo "server is stopping !"
;;
restart)
echo "server is restarting !"
;;
*)
echo "you input is error,please try again!"
;;
esac
[email protected]-unknown85879:~$ sh test.sh stop
server is stopping !
[email protected]-unknown85879:~$ sh test.sh
you input is error,please try again!
[email protected]-unknown85879:~$ sh test.sh start
server is starting !
加参数选项的示例:
#!/bin/bash
while getopts :b:d: OPT &> /dev/null;
do
case $OPT in
b)
echo "is b"
echo $OPTARG
;;
d)
echo "is d"
echo $OPTARG
;;
*)
echo "error "
exit 7
;;
esac
done
[email protected]-unknown85879:~$ sh getopt.sh -d dd
is d
dd
[email protected]-unknown85879:~$ sh getopt.sh -b hello
is b
hello
6、shell的函数
几乎所有语言都会有函数,shell也不例外,下面看看函数的语法:
格式:
function functionname ()
{
body;
}
调用方式:直接函数名调用
functionname
示例1:我将之前的用于case语句的实例,改写成用函数实现看看
[email protected]-unknown85879:~$ cat test.sh
#!/bin/bash
function stop ()
{
echo "your chiose is stop ,stopping !"
}
function start ()
{
echo "your chiose is start,startting !"
}
function restart ()
{
echo "your chiose is restart,restartting !"
}
if [ "$1" = "stop" ];then
stop
elif [ "$1" = "start" ];then
start
elif [ "$1" = "restart" ];then
restart
else
echo "your input is error ,try again !"
fi
[email protected]-unknown85879:~$ sh test.sh
your input is error ,try again !
[email protected]-unknown85879:~$ sh test.sh stop
your chiose is stop ,stopping !
[email protected]-unknown85879:~$ sh test.sh start
your chiose is start,startting !
[email protected]-unknown85879:~$ sh test.sh restart
your chiose is restart,restartting !
[email protected]-unknown85879:~$
这里注意对比字符串时,if里面的变量要双引号括起来,否则会报错,== 和 =在这里是等价的。
四、shell的环境变量
1、环境变量有哪些,如何保存和生效?
(1)环境变量有很多,按不同的作用域分有系统环境变量如path,用户环境变量如用户自定义的家目录,或者命令别名,应用环境变量如jdk环境变量。
如何查看:直接输入 env
查看某个环境变量:如查看path: echo $PATH
(2)按作用时间来看有临时环境变量,有永久环境变量:
比如我们的$HOME是一个永久环境变量,我们要临时修改它,直接export 一下:
[email protected]-unknown85879:~$ echo $HOME ---修改前
/home/zhugeling
[email protected]-unknown85879:~$ export HOME=‘/home/tmp‘
[email protected]-unknown85879:/home/zhugeling$
[email protected]-unknown85879:/home/zhugeling$ echo $HOME ---修改后
/home/tmp
说明这种事临时生效,系统重启,或重新打开一个shell终端是会失效的。
环境变量永久生效的办法:直接修改配置文件或将修改保存到配置文件
(3)、常见环境变量的配置文件有哪些?
系统全局作用:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
生效: source 路径
对当前用户起作用:
~/.bash_profile
~/..bashrc
生效: source 路径
对应用本身起作用的(不同应用配置文件名和路径不一样):
/etc/ssh/sshd_config
/etc/ssh/ssh_config
生效:一般是重启应用或reload
2、shell的ps1/ps2/ps3有什么用:
(1)ps1:
先来个例子看看是什么作用的
[email protected]-unknown85880:~/tmp$ export PS1=‘ >‘
20:24:06 >
20:24:07 >
说明:从上例可以看到ps1可以通过export方式改变系统的终端提示符,ps1就是命令行提示符的环境变量。上面通过export改变环境变量的值,将显示结果改成时间而达到的效果。它还有更多其他参数如:
a搜索 显示系统日期,格式:星期 日期
例:PS1="d >" 结果:六 10月 24 >
A 显示系统时间,格式:HH:MM
例:PS1="A >" 结果:21:04 >
显示系统时间,格式:HH:MM:SS (24小时制)
例:PS1=" >" 结果:21:04:32 >
T 显示系统时间,格式:HH:MM:SS (12小时制)
例:PS1="T >" 结果:09:04:32 >
h 显示主机名称(简称)
例:PS1="h >" 结果:CentOS >
H 显示主机名称(全称)
默认值是:[[email protected]h W]$
刚刚只是临时修改,如果要长久生效怎么办?
放在个人家目录下的 .bashrc吧
如:
export PS1=’ h’
如果要全局生效呢?
我们来试试,我修改了/etc/profile的文件,后面追加 export PS1=’ h’,source之后,root用户立马生效,但是登录其他用户发现没效果。
排查发现用户下的.bashrc是有对PS1设置的:
if [ "$color_prompt" = yes ]; then
PS1=‘${debian_chroot:+($debian_chroot)}[ 33[01;32m][email protected]h[ 33[00m]:[ 33[01;34m]w[ 33[00m]$ ‘
else
PS1=‘${debian_chroot:+($debian_chroot)}[email protected]h:w$ ‘
fi
unset color_prompt force_color_prompt
经查资料,原来是登录读取配置文件的先后顺序也有关,最后读取的当然是最终起作用了:
/etc/profile ->.bash_profile -> .bashrc -> /etc/bashrc
那我们改 /etc/bashrc 试试:
[email protected]-unknown85880:~# source /etc/bash.bashrc
20:49:05newbie-unknown85880:
20:49:06newbie-unknown85880:
20:49:06newbie-unknown85880:
20:49:06newbie-unknown85880:tail -1 /etc/bash.bashrc
export PS1=‘ h:‘
果然如此。
Shell还有PS2,PS3,ps2是Shell的次提示符,PS3是Shell脚本中使用select时的提示符
举例:
默认显示如下:
[email protected]-unknown85881:~$ sh test.sh
1) mon
2) tue
3) wed
4) exit
#? 1
Monday
#? 2
Tuesday
#? 3
Wednesday
#? ^C
修改PS3=’ myshell’:
[email protected]-unknown85881:~$ export PS3=‘ mysell:‘
[email protected]-unknown85881:~$ sh test.sh
1) mon
2) tue
3) wed
4) exit
mysell:1
Monday
mysell:2
Tuesday
mysell:
其他的生效顺序,长久生效配置跟ps1是一样的。
3、登录方式不一样对环境变量的影响:
有时候我们会碰到,用不同的用户去启动一个应用时会报错,除了文件权限不一样之外,通常还有另外一个原因就是不同用户的环境便令不一样。
(1)登录shell和非登shel:
登录shell:是通过账号密码登录进入shell的(或者通过”–login”选项生成的shel)
非登录shell:不需要账号密码,直接通过bash命令或者桌面右键打开的终端。
[email protected]-unknown85879:/etc/ssh# echo $$
26497
[email protected]-unknown85879:/etc/ssh# bash
[email protected]-unknown85879:/etc/ssh# echo $$ ---shell的进程ID跟之前不一样
30154
[email protected]-unknown85879:/etc/ssh# exit
exit
正常登录文件的读取调用关系:
执行/etc/profile中的命令,然后/etc/profile调用/etc/profile.d目录下的所有脚本;然后执行~/.bash_profile,~/.bash_profile调用~/.bashrc,最后~/.bashrc又调用/etc/bashrc
非登录shell:
执行~/.bashrc,~/.bashrc调用/etc/bashrc,然后调用/etc/profile.d/*下的所有脚本。
区别:非登录shell不会重新加载/etc/profile,而且顺序也不一样,如果你的环境变量设置是在/etc/profile和~/.bash_profile ,建议重新登录或source一下对应的配置文件。
登录方式:su user 和 su - user的区别:
su user :只是切换了用户,切换了权限,但是环境变量没变。
su - user : 切换了用户,切换了权限,也切换了环境变量
[email protected]-unknown85879:/home/zhugeling$ su root
Password:
[email protected]-unknown85879:/home/zhugeling# ---目录没换
[email protected]-unknown85879:/home/zhugeling$ su - root
Password:
[email protected]-unknown85879:~# ---目录换了
(2)交互式shell和非交互式shell:
我们把命令行终端这种输入一个命令,shell、去执行,然后输出结果,这种叫交互式shell,非交互式shell是指shell自己一直执行到执行完就退出shell的模式,脚本执行就是典型的非交互式shell。
我们可以通过echo $- 来判断当前是什么类型的shell:
[email protected]-unknown85879:/etc/ssh# echo $- --交互式
himBHs
[email protected]-unknown85879:/etc/ssh# cat test.sh
echo $-
[email protected]-unknown85879:/etc/ssh# sh test.sh ---非交互式
hB
在环境变量上的区别:
交互式shell:就是当前登录用户的环境变量(根据登录方式不同也会有区别)
非交互式shell:继承当前登录用户的环境变量,在此基础上shell可以在脚本里加载其他环境变量,如通过export PATH=’..’ 等
五、正则表达式和通配符的区别
(1)、作用对象和范围不一样:
作用对象:
通配符用于Linux的shell命令(如文件名相关操作),如常结合find ,cp,mv等命令使用
正字表达是是用于文本字符串或者标准输出里的内容的过滤和匹配
作用范围:
通配符必须在unix环境或类Unix环境中使用
正则表达式在很多语言中都支持,是一种标准,可以写在代码中,跨平台性好。
(2)解释器不一样:
通配符是Linux系统本身支持的,由shell去解析执行。
正则表达式在使用过程中有可能是shell去解析,也有可能是awk,perl等支持正则的命令去解析,就看使用方式是怎么用。
如:
[email protected]-unknown85879:/home/zhugeling$ ls -l logrotate.sh_* |grep "*" ---这里前面*号是通配符,后面*号只是一个*号
-rw-r--r-- 1 zhugeling zhugeling 1628 Feb 1 12:13 logrotate.sh_v*
[email protected]-unknown85879:/home/zhugeling$ ls -l logrotate.sh_* ---这里*号是通配符号
-rw-r--r-- 1 zhugeling zhugeling 1628 Feb 1 12:13 logrotate.sh_v*
-rw-r--r-- 1 zhugeling zhugeling 969 Jan 30 20:34 logrotate.sh_v1
-rw-r--r-- 1 zhugeling zhugeling 1940 Jan 31 11:20 logrotate.sh_v2
-rw-r--r-- 1 zhugeling zhugeling 1628 Jan 31 12:11 logrotate.sh_v3
[email protected]-unknown85879:/home/zhugeling$ ls -l logrotate.sh_* |grep ‘v*‘ --这里*号是正则修饰符
-rw-r--r-- 1 zhugeling zhugeling 1628 Feb 1 12:13 logrotate.sh_v*
-rw-r--r-- 1 zhugeling zhugeling 969 Jan 30 20:34 logrotate.sh_v1
-rw-r--r-- 1 zhugeling zhugeling 1940 Jan 31 11:20 logrotate.sh_v2
-rw-r--r-- 1 zhugeling zhugeling 1628 Jan