执行算术运算

val=`expr $a + $b`

运算符

符号说明示例
!非运算[ ! false ]
-o或运算[ $a -lt 20 -o $b -gt 20 ]
-a与运算[ $a -lt 20 -a $b -gt 20 ]
=相等检测[ $a = $b ]
!=不相等检测[ $a != $b ]
-z字符串长度是否为 0,为 0 则返回 true[ -z $a ]
-n字符串长度不为 0, 不为 0 返回 true[ -n $a ]
str检测字符串是否为空,不为空返回 true[ $a ]
-b检测文件是否是块设备文件[ -b $file ]
-c检测文件是否是字符设备..
-d检测文件是否为目录[ -d $file ]
-f检测文件是否为普通文件[ -f $file ]
-r检测文件是否可读..
-w检测文件是否可写..
-x检测文件是否可执行..
-s检测文件是否为空..
-e检测文件是否存在..

特殊变量

变量含义
$0当前脚本的文件名
$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数
$#传递给脚本或函数的参数个数
$*传递给脚本或函数的所有参数,所有参数被当做一个词,例如 “1 2 3”
$@传递给脚本或函数的所有参数,每个参数当做一个词,用双引号包含,例如"1" “2” “3”
$?上个命令的退出状态,或函数的返回值
$$当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID

POSIX 程序退出状态

状态码含义
0命令成功退出
> 0在重定向或者单词展开期间(~、变量、命令、算术展开以及单词切割)失败
1 - 125命令不成功退出。特定的退出值的含义,有各个命令自行定义
126命令找到了,但是文件无法执行
127命令没有找到
> 128命令因收到信号而死亡

输入输出重定向

命令说明
command > file将输出重定向到 file。
command > file将输出以追加的方式重定向到 file。
n > file将文件描述符为 n 的文件重定向到 file。
n » file将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m将输出文件 m 和 n 合并。
n <& m将输入文件 m 和 n 合并。
« tag将开始标记 tag 和结束标记 tag 之间的内容作为输入。

文件包含

使用.或者source包含文件

. filename
source filename

被包含文件不需要有执行权限

使用函数

下面是函数基本结构

# 直接使用函数名称即可,前面可选的添加function function_name
function_name(){

    # 使用$#,$*,$@以及$0-$n获取函数名以及其它参数
    val="$1"

    # 带返回值,可选,返回值只能是整数(状态码)
    # 如果要返回结果的话,使用全局变量
    return $val
}

函数调用

# 调用函数直接使用函数名称即可,后面可以空格隔开使用多个参数
function_name 1 2 3 4
# 使用$?变量获取返回值
ret=$?

常用代码片段

列出目录下的所有文件

下面的代码列出了 downloads 目录下所有的 xlsx 文件,这里要注意的是,如果要列出所有文件,使用"$watch_dir"/*这种形式。

watch_dir="/Users/mylxsw/Downloads"
# 避免目录下没有匹配文件时返回带有*的结果
shopt -s nullglob
for file in "$watch_dir"/*.xlsx
do
    echo $file
done

for file in "$watch_dir"/*/    # 列出所有目录
do
    echo $file
done

参考 How to get the list of files in a directory in a shell script?Bash Shell Loop Over Set of Files

从标准输入循环读取

while read line
do
    if [ $line != 'EOF' ]
    then
        echo $line
    fi
done

日期时间处理

获取当前日期

# 输出: 20161023
echo $(date +%Y%m%d)

时间比较

时间比较可以先转换为 UNIX 时间戳,然后直接比较时间戳大小即可。

time1=`date +%s`
time2=`date -d '2016-10-25 17:20:13' +%s`

if [ $time1 -gt $time2 ]; then
    echo "time1 > time2"
else
    echo "time1 < time2"
fi