注意点

通配符和正则表达式不同 特别是 * 这个符号 通配符:零到无限多个字符的意思 正则表达式:重复零到无限多个前一个字符的意思

${name} 取出变量结果 $(date) 在括号中执行命令,然后读取出命令结果,拿到它 `` 和上一个类似 $name 取出变量结果

echo "今天日期:$(date)"

数值计算

shell 的一些基础命令,只支持整数的运算,小数的计算需要如 bc 这样的命令

(( ))

echo $((3 + 4))  # 7
echo $((10 / 3))  # 3
echo $((5 ** 2))  # 25
echo $((3 < 4 && 5 == 5)) # 1
echo $((2 * 1.5)) # 报错

num=5
echo $((num = num * 3)) # 15
echo $num   # 15
b=$((num = num * 3))  # b = 15
echo $((b++))

let

效果等同于双括号 效率更低一点

num=8
num=num+2         # echo $num --> num + 2
let num=num+2     # echo $num --> 10

expr

必须以参数的形式传递,所以要有空格 但是一些元字符有特殊含义,需要加转移字符

expr 5 \* 3           # 15
expr 5 + 3            # 8
expr length 123abc    # 6
expr 5 \> 7           # 0

也可模式匹配 : 冒号,计算字符串的数量 .* 任意的字符重复 0 次或者多次 所以可用于 shell 脚本中判断后缀是否正确,因为不正确会返回 0

expr ycpng.png ":" ".*"       # 6
expr ycpng.png ":" ".*p"      # 7
expr ycpng.png ":" ".*png"    # 9

name=ycpng.png
echo ${name#*png}            # .png
# 注意区分正则表达式和变量删除替换的区别

bc

# 交互式
bc # 然后进入一个界面,自己输入数字和运算符即可,不用空格都行

# 管道符运用
echo "4.2*3" | bc      # 12.6
echo "10/3" | bc       # 3
echo {1..100} | tr " " "+" | bc  # 5050
# 这个的语法是生成 1~100 序列,原本是空格,然后使用 tr 命令换成加号,然后利用管道符给 bc
seq -s "+" 100 | bc
# 这个语法同理,只是使用 seq,这个是生成序列,默认是一换行分隔,-s 更改分隔符

# 双括号
echo $((`seq -s "+" 100`))
# expr
seq -s " + " 100 | xargs expr

基础

#---------------------------------------------------------
##### if
# 注意括号内左右两边必须有空格
if [ num -ne 1 ]
    then
        执行体
elif  条件表达式
    then
        执行体
else
    执行体
fi

# 也可这样
if  条件表达式; then 
    执行体

# ---------------------------------------------------------
###### case 语句
case $op in
    "1" )
        执行体
        ;;
    "2" )
        执行体
        ;;
    "*" )    #---------> 都没匹配上,执行这个,类似于 C++ default
        执行体
        ;;
esac
# ---------------------------------------------------
##### while 循环
while [ 条件判断式 ]
    do
        执行体
    done


# for 循环
for str in I am a handsome boy
    do
        执行体
    done

s=0
for (( i=1; i<=10; i++ ))
    do
        s=$(( $s+$i ))
    done

echo $s   # 55
#--------------------------------------------------------------
####### 函数
# function 关键字可省略
function func(){
    执行体
    return 返回值   # $? 状态码
}
# 调用 
func

# 函数里定义的变量为局部变量
# return 是结束函数运行,返回一个值,给脚本
# exit 是结束 shell 环境,返回一个值为当前的 shell
# return 只能写在函数里
# 函数内,用 local 定义局部变量
function func(){
    echo ok
    echo no
    return 0
}
func

# 函数单独写在一个文件里,需要用 source 读取
# 在一个 bash 文件中写这段代码,只定义,不执行
# 调用 source 或者 . 命令,能够加载当前函数到当前 shell 环境中
# 然后直接调用函数就能执行,但是是临时的,重新进入当前 shell,环境中的这个函数不存在
function func(){
    echo ok
    echo no
    return 0
}

# 传参
function func(){
    echo $1
    echo $2
    return 0
}
func $1 $2
# 执行
bash a.sh "a" "b" 

条件测试

在这里的运用 || 和 && 这符号有所区别 && 是指前者成功,也执行后者;前者失败,都不执行 || 是指前者失败,执行后者,前者成功,不执行后者

test

# 语法:test -e filename
-e  该文件是否存在(目录、文件、等等都能)
-f  该文件名是否为文件(file)
-d  该文件名是否为目录(directory)
-c  该文件名是否为一个 character device 装置
-s  该文件名是否为一个 Socket 文件
-p  该文件名是否为一个 FIFO(pipe)文件
-n  内容是否不为空,不空为 true

# 文件权限检测   test -r filename
-r  检测文件名是否具有可读的属性
-w  检测文件名是否具有可写的属性
-x  检测文件名是否具有可执行的属性
-u  检测文件名是否具有 SUID 的属性
-g  检测文件名是否具有 SGID的属性
-k  检测文件名是否具有 Sticky bit 属性
-s  检测文件名是否为非空白的文件

# 两个整数之间的判定,例如 test n1 -eq n2
-eq  两数值相等(equal)
-ne  两数值不等(not equal)
-gt  n1 大于 n2(greater than)
-lt  n1 小于 n2(less than)
-ge  n1 大于等于 n2(greater than or equal)
-le  n1 小于等于 n2()less than or equa1)

# 多重判定
-a  两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 和 x 权限时,才回传     true
-o  两状况任何一个成立
!   反向状态,如 test ! -x file,当 file 不具有 x 时,返回 true

# 判断两字符串数据
test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true
test -n string 判定字符串是否为 非0 ?若 string 为空字符串,则为 false。
注:-n 亦可省略
test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false

中括号

作用和 test 一样 和 if 一样,需要左右两边加空格

[ -f "$filename" ]  # 注意这里需要加双引号,条件测试里,都需要

[ -f "$filename" ] && echo ok  # 和 test 参数一致,使用同理

双中括号

[[ 条件判断 ]]
# 验证文件是否有对应的权限
# 注意:root 需要排除,都具有权限

各种比较逻辑

# 字符串比较
# 符号前后需要空格
==    判断是否相等
!=   判断是不等的
!    去结果的反义
# 示例
name="hh"
[ "$name" == "hh" ] && echo ok || echo no
[ ! -f filename ] && echo ok || echo no

# 数值比较
# test 中以及 [] 中,使用参数如 -ne
# 在 (()) 以及 [[]] 中使用 <=   =或者==
[[ 1 < 2 ]] && echo ok || echo no      # ok
[ 1 \< 2 ] && echo ok || echo no       # 如果使用 [] 需要使用转义字符
[ 1 -lt 2 ] && echo ok || echo no      # ok
[[ 1 -lt 2 ]] && echo ok || echo no    # ok

# 逻辑运算符
# test 和 [] 中使用 -a, -o !,在 [[]] 和 (()) 使用 && || !

只管努力,剩下的交给天意