概述
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
set 命令
set -e
表示一旦脚本中有命令的返回值为非0,则脚本立即退出,后续命令不再执行;
set -o pipefail
表示在管道连接的命令序列中,只要有任何一个命令返回非0值,则整个管道返回非0值,即使最后一个命令返回0.
set -u
遇到不存在的变量就会报错,并停止执行。效果等同 set -o nounset
常用特殊变量
变量 |
含义 |
$0 |
当前脚本的文件名 |
$n |
传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2 |
$# |
传递给脚本或函数的参数个数 |
$* |
传递给脚本或函数的所有参数 |
$@ |
传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同 |
$? |
上个命令的退出状态,或函数的返回值。成功返回0,失败返回1 |
$$ |
当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID |
$*
和 $@
都是将参数一个一个返回 。
"$*"
将所有参数当做一个整体字符串返回 , "$@"
将参数一个一个返回。
数值判断
命令 |
含义 |
-eq |
等于 |
-ne |
不等于 |
-gt |
大于 |
-lt |
小于 |
-ge |
大于等于 |
-le |
小于等于 |
1 2 3 4
| # 判断脚本传入参数个数是否为0 if [ $# -gt 0 ]; then echo "Parameter Error!" fi
|
逻辑判断
命令 |
含义 |
-a |
逻辑与 |
-o |
逻辑或 |
! |
逻辑非 |
1 2 3
| if [ "None" = MODEL -a "None" = IMAGE ]; then echo "Parameter Error!" fi
|
字符串判断
命令 |
含义 |
= |
字符串是否相等 |
!= |
字符串是否不相等 |
-n |
字符串的长度是否不等于0 |
-z |
字符串的长度是否等于0 |
1 2 3 4 5
| STRING="" if [ -n "${STRING}" ]; then echo "Everything" fi # 注意 若${STRING}不加双引号, 则也是认为字符串长度大于0
|
去除字符串的双引号
shell 判断文件是否存在
文件/目录判断
命令 |
含义 |
-r |
文件是否存在且可读 |
-w |
文件是否存在且可写 |
-s |
文件是否存在且长度非0 |
-f |
文件是否存在且是普通文件 |
-d |
目录是否存在 |
1 2 3 4 5
| if [ ! -d "/data/" ];then mkdir /data else echo "文件夹已经存在" fi
|
提取文件名和目录名
从路径中获取文件名
1 2 3
| PATH="/data/local/tmp/file.txt" echo ${PATH##*/} # 结果为 file.txt
|
1 2 3 4 5 6
| PATH="/data/local/tmp/file.txt" echo $(basename ${PATH}) # 结果为 file.txt
echo $(basename ${PATH} .txt) # 结果为 file
|
从路径中获取文件后缀名
1 2 3 4 5 6 7 8
| PATH="/data/local/tmp/file.tar.gz" # 返回从左边算起的最后一个'.'(不含该字符)的右边的内容 echo ${PATH##*.} # 结果为 gz
# 返回从左边算起第一个'.'(不含该字符)的右边部分的内容 echo ${PATH#*.} # 结果为 tar.gz
|
从路径中获取文件所在目录路径
1 2 3 4 5 6
| PATH="/data/local/tmp/file.txt" echo ${PATH%/*} # 结果为 /data/local/tmp
echo ${PATH%%.*} # 结果为 /data/local/tmp/file
|
1 2 3 4 5 6 7
| PATH="/data/local/tmp/file.txt" echo $(dirname ${PATH}) # 结果为 /data/local/tmp
PATH="/data/local/tmp echo $(dirname ${PATH}) # 结果为 /data/local
|
变量替换
命令 |
含义 |
$variable |
保存在variable中的值 |
${variable} |
保存在variable中的值 |
${variable}:-string |
如果variable值为非空, 则值为variable, 否则为string |
${variable}:+string |
如果variable值为非空, 则值为string, 否则为空 |
${variable}:=string |
如果variable值为非空, 则值为variable, 否则为string且variable的值设为string |
${variable}?string |
如果variable值为非空, 则值为variable,否则显示string并退出 |
作用: 使用户能够检查变量的值并根据选项改变它的值。
数组遍历
for循环
带数组下标
1 2 3 4 5
| MODELS=("AAA" "BBB" "CCC") for ((i = 0; i < ${#MODELS[@]}; i++)) do echo $i ${MODELS[i]} done
|
1 2 3 4 5
| MODELS=("AAA" "BBB" "CCC") for i in "${!MODELS[@]}" do printf "%s\t%s\n" "$i" "${MODELS[$i]}" done
|
不带数组下标
1 2 3 4 5 6
| # @ 可用 * 替代 MODELS=("AAA" "BBB" "CCC") for MODEL in ${MODELS[@]} do echo $MODEL done
|
While循环
1 2 3 4 5 6 7 8 9
| MODELS=("AAA" "BBB" "CCC") i=0 while [ $i -lt ${#MODELS[@]} ] #当变量(下标)小于数组长度时进入循环体 do echo ${MODELS[$i]} #按下标打印数组元素 let i++ done
|
解析脚本传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #!/bin/sh
set -e
current_dir=$(cd `dirname $0`; pwd)
USAGE_LINE="Usage: $0 [OPTION] [SELECT]\n \ --input-model\t\t测试模型路径\n \ --input-picture\t测试模型的输入数据文件\n \ --help\t\t\t帮助\n \ e.g: $0 --input-model=./test.pb --input-picture=./test.jpg \ "
for opt in "${@}"; do case $opt in --input-model=*) export input_model="$(echo "$opt" | cut -d '=' -f 2-)" ;; --input-picture=*) export input_picture="$(echo "$opt" | cut -d '=' -f 2-)" ;; --help) echo ${USAGE_LINE} exit ;; *) echo ${USAGE_LINE} exit ;; esac done
echo ${input_model} ${input_picture}
|
格式化输出
输出类型
%ns
:输出字符串。n 是数字,指代输出几个字符。
%ni
:输出整数。n 是数字,指代输出几个数字。
%m.nf
: 输出浮点数。m 和 n 是数字,指代输出的整数位数和小数位数。如 %8.2f 代表共输出 8 位数,其中 2 位是小数,6 位是整数。
输出格式
\a
: 输出警告声音;
\b
:输出退格键,也就是 Backspaced 键;
\f
:清除屏幕;
\n
:换行;
\r
:回车,也就是 Enter 键;
\t
:水平输出退格键,也就是 Tab 键;
\v
:垂直输出退格键,也就是 Tab 键;
示例
有这样一个文本 tmp.txt
1 2 3 4
| ID Name PHP Linux MySQL Average 1 Liming 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Gao 99 83 93 91.66
|
格式化输出
1 2 3 4 5 6 7 8 9 10 11 12
| printf '%s\t %s\t %s\t %s\t %s\t %s\t\n' $(cat tmp.txt) # 输出结果 ID Name PHP Linux MySQL Average 1 Liming 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Gao 99 83 93 91.66
printf '%i\t %s\t %i\t %i\t %i\t %.2f\t\n' $(cat tmp.txt | grep -v Name) # 输出结果 1 Liming 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Gao 99 83 93 91.66
|