0. 所谓引号
字符串符(引号)
序号 | 符号 | 作用 | 示例 |
---|---|---|---|
1 | ‘’ | 两个单引号。单引号括住的内容,被视为常量字符串,引号内的禁止变量扩展,并且单引号字符串中不能出现单引号(对单引号使用转义符后也不行) | echo '$PATH';#输出$PATH |
2 | “” | 两个双引号。双引号包围的内容可以允许变量扩展,可以包含双引号,但需要转义。 | echo "$PATH";#输出环境变量PATH的内容 |
1. [ expr ] 条件判断
注意[]和expr之间,必须有空格!!!可以想想test命令和expr之间的空格
等同于test expr,用于if条件判断。可以参考《Shell之if语法和常用场景》
test的三个基本作用是判断文件、判断字符串、判断整数。支持使用 ”与或非“ 将表达式连接起来。
test中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq, -gt这种形式。
expr, 条件表达式,都是逻辑表达式。
文件表达式
if [-d file] # 如果目录存在
if [-f file] # 如果文件存在
if [-e file] # 如果文件或目录存在
if [-x file] # 如果文件存在且为可执行文件
整数变量表达式
if [ int1 -eq int2 ] 如果int1等于int2
if [ int1 -ne int2 ] 如果不等于
if [ int1 -ge int2 ] 如果>=
if [ int1 -gt int2 ] 如果>
if [ int1 -le int2 ] 如果<=
if [ int1 -lt int2 ] 如果<
字符串变量表达式
If [ $a = $b ] 如果string1等于string2
字符串允许使用赋值号做等号
if [ $string1 != $string2 ] 如果string1不等于string2
if [ -n $string ] 如果string 非空(非0),返回0(true)
if [ -z $string ] 如果string 为空
if [ $sting ] 如果string 非空,返回0 (和-n类似)
同样的,空格!!!!是否有空格是天壤之别,有空格是逻辑表达式,没有空格是算数表达式
[root@app17027 scripts]# if [[ 5=3 ]];then echo uuu ;else echo yyy ; fi
uuu
[root@app17027 scripts]# if [[ 5 = 3 ]];then echo uuu ;else echo yyy ; fi
yyy
[root@app17027 scripts]# if [ "sssf"="sss" ];then echo uuu ;else echo yyy ; fi
uuu
[root@app17027 scripts]# if [ "sssf" = "sss" ];then echo uuu ;else echo yyy ; fi
yyy
2. [[ ]] 条件判断
[[]]是关键字
除了[]支持的判断外,
支持bash中的通配符扩展,如:[[ hest = h??t ]] 、[ hest = h*t ]]
支持正则匹配判断,
filelist="lvlvcheck dablelvlv checklvlv"
for file in $filelist
do
if [[ $file =~ lvlv$ ]]
then
echo $file
fi
done
正则表达式不能使用单引号或者双引号,否则会被当做普通字符串。 如果想使Shell if不匹配指定的正则表达式,可以使用Shell的逻辑非运算符感叹号!
if [[ ! $file =~ check$ ]]
虽然[[]]支持除了gt,eq那些外,也支持+ - * /运算符,但是最好不要用,实在想用,就用(())。
使用 (( )) 时,不需要空格分隔各值和运算符,使用 [[ ]] 时需要用空格分隔各值和运算符。
3. ()
一般用于表达式的分隔。
有个有意思的,可以用于定义数组。然后通过${}来取数组里的值。
A="a b c def" # 定义字符串
A=(a b c def) # 定义字符数组
#字符串的话,没法取
[root@app17027 scripts]# A="a b c d e f"
[root@app17027 scripts]# echo ${A[0]}
a b c d e f
#数组的话,可以取指定序号的变量值
4. (( )) 算数计算
在 (( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用。
只能用于整数计算。不能用于浮点数。
+加 -减 *乘 /除 %取余数 &与 |或 ^ !非
5. $() 命令替换
等同于反引号` 。$( )的弊端是,并不是所有的类unix系统都支持这种方式,但反引号是肯定支持的。
先完成命令执行,将其结果替换出来,组成新的命令行。
这个原理简单,但是命令执行的结果,很有意思。
要区分命令执行的结果和exit状态码。
exit状态码通过$?来获取上一个命令执行的exit状态码。
命令执行结果一般是stdout打印出来的。
[root@app17027 scripts]# cat printOSVersion.sh
cat /etc/redhat-release
exit 1
[root@app17027 scripts]# aaa=`./printOSVersion.sh`
[root@app17027 scripts]# echo $?
1
[root@app17027 scripts]# echo $aaa
CentOS release 6.8 (Final)
6. $(()) 返回算数计算的结果
在 $(( )) 中的变量名称,可于其前面加 $ 符号来替换,也可以不用。
各种进制转换为十进制
[root@app17027 scripts]# if [ $((16#ff)) -gt $((16#bb)) ];then echo uuu ;else echo yyy ; fi
uuu
{}
{{}}
7. ${}
7.1. 变量
${var}与$var等同。但是,如果$AB和${A}B是不一样的。。。
[root@localhost ~]# A=Linux
[root@localhost ~]# echo $AB #表示变量AB
[root@localhost ~]# echo ${A}B #表示变量A后连接着B
LinuxB
7.2. 字符串命令
先赋值一个变量为一个路径,如下:
file=/dir1/dir2/dir3/my.file.txt
以下样例全部以这个file为字符串。
7.2.1. 取子串
${file::}
从index开始(包括index位置的字符),length个字符。注意,index从0开始。
命令 | 解释 | 结果 |
---|---|---|
${file:0:5} | 提取最左边的 5 个字节 | /dir1 |
${file:5:5} | 提取第 5 个字节右边的连续 5 个字节 | /dir2 |
${#file} | 获取变量长度 | 27 |
7.2.2. 字符替换
${file/src/dest} # 只替换第一个匹配
${file//src/dest} # 全部替换
命令 | 解释 | 结果 |
---|---|---|
${file/dir/path} | 将第一个 dir 替换为 path | /path1/dir2/dir3/my.file.txt |
${file//dir/path} | 将全部 dir 替换为 path | /path1/path2/path3/my.file.txt |
7.2.3. 取路径、文件名、后缀
# 是去掉左边(在键盘上 # 在 $ 之左边)
% 是去掉右边(在键盘上 % 在 $ 之右边)
单一符号是最小匹配,两个符号是最大匹配
*是用来匹配不要的字符,也就是想要去掉的那部分
还有指定字符分隔号,与*配合,决定取哪部分
命令 解释 结果
${file#*/} 拿掉第一条 / 及其左边的字符串 dir1/dir2/dir3/my.file.txt
[root@localhost ~]# echo ${file#*/}
dir1/dir2/dir3/my.file.txt
${file##*/} 拿掉最后一条 / 及其左边的字符串 my.file.txt
[root@localhost ~]# echo ${file##*/}
my.file.txt
${file#*.} 拿掉第一个 . 及其左边的字符串 file.txt
[root@localhost ~]# echo ${file#*.}
file.txt
${file##*.} 拿掉最后一个 . 及其左边的字符串 txt
[root@localhost ~]# echo ${file##*.}
txt
${file%/*} 拿掉最后一条 / 及其右边的字符串 /dir1/dir2/dir3
[root@localhost ~]# echo ${file%/*}
/dir1/dir2/dir3
${file%%/*} 拿掉第一条 / 及其右边的字符串 (空值)
[root@localhost ~]# echo ${file%%/*}
(空值)
${file%.*} 拿掉最后一个 . 及其右边的字符串 /dir1/dir2/dir3/my.file
[root@localhost ~]# echo ${file%.*}
/dir1/dir2/dir3/my.file
${file%%.*} 拿掉第一个 . 及其右边的字符串 /dir1/dir2/dir3/my
[root@localhost ~]# echo ${file%%.*}
/dir1/dir2/dir3/my
还有好玩的命令
获取文件绝对路径
$(readlink -f $f)
$ dirname ‘/home/lalor/a.txt'
/home/lalor
$ basename ‘/home/lalor/a.txt'
a.txt
7.3. 数组命令
命令 | 解释 | 结果 |
---|---|---|
${A[@]} | 返回数组全部元素 | a b c def |
${A[*]} | 同上 | a b c def |
${A[0]} | 返回数组第一个元素 | a |
${#A[@]} | 返回数组元素总个数 | 4 |
${#A[*]} | 同上 | 4 |
${#A[3]} | 返回第四个元素的长度,即def的长度 | 3 |
A[3]=xzy | 则是将第四个组数重新定义为 | xyz |
8. ${{}}
没有这个。
9. 关于和if的搭配
if condition
这个condition,有意思。
最常见的是 []和[[]],
但是也可以有command,这里condition就是command的exit状态码,而不是命令执行结果,
-
再一个是(())算数表达式,这个表达式一般看成逻辑表达式。而且不用加$为$(())。
[root@app17027 scripts]# if $(( 5 > 3 )) ;then echo uuu ; else echo yyy; fi
-bash: 1: command not found
yyy
10. 是command还是expr
关于(()),到底看成command还是expr,呵呵。
[root@app17027 scripts]# (( 5 < 3 ))
[root@app17027 scripts]# echo $?
1
[root@app17027 scripts]# (( 5 > 3 ))
[root@app17027 scripts]# echo $?
0
[root@app17027 scripts]# [ 5 -gt 3 ]
[root@app17027 scripts]# echo $?
0
[root@app17027 scripts]# [ 5 -gt 9 ]
[root@app17027 scripts]# echo $?
1
[root@app17027 scripts]# bbb = [ 5 -gt 9 ]
-bash: bbb: command not found
[root@app17027 scripts]# bbb=[ 5 -gt 9 ]
-bash: 5: command not found
[root@app17027 scripts]# ccc = (( 5 > 3 ))
-bash: syntax error near unexpected token `('
[root@app17027 scripts]# ccc=$(( 5 > 3 ))
参考链接
https://www.cnblogs.com/chengd/p/7803664.html
http://c.biancheng.net/view/2480.html
https://blog.csdn.net/sunxiaopengsun/article/details/82656059
https://blog.csdn.net/K346K346/article/details/51819236