环境声明
#!/bin/bash
or #!/bin/sh
or #!/usr/bin/env bash
文件扩展名
Shell脚本扩展名为.sh
,如 test.sh
执行脚本
执行权限
chmod +x file
,如 chmod +x ./test.sh
运行
./test.sh
变量
定义变量
a=12
或 _var="apple"
使用变量
$a
或 ${_var}
只读变量
readonly var
字符串
单引号
- 单引号内的任何字符都会原样输出,单引号字符串中的变量是无效的
- 单引号内可成对出现单引号,作为字符串拼接使用
双引号
- 可以有变量
- 可以出现转义字符
字符串长度
${#var}
str="Money"
echo ${#str}
提取字符串
${var:index:count}
str="Monkey"
echo ${str:0:3}
查找字符串
expr index String subString
str="I have an apple."
echo `expr index "$str" a`
数组
定义数组
array=(a b c)
读取数组
- 获取第一个元素
${array[0]}
- 获取所有元素
${array[@]}
传递参数
-
$0
执行的文件名 -
$1
第一个参数,以此类推 -
$#
参数个数 -
$*
以一个单字符串显示所有参数;相当于传递一个参数 -
$@
与$*
类似,但是使用时加引号;相当于传递所有参数 -
$$
脚本运行的当前进程号
运算符
算术运算符
使用
expr
命令
-
+
-
*
/
%
=
加、减、乘、除、取余、赋值 -
==
!=
相等、不相等
关系运算符
只支持数字
-
-eq
相等equal
-
-ne
不相等not equal
-
-gt
大于greater than
-
-lt
小于less than
-
-ge
大于等于greater and equal
-
-le
小于等于less and equal
布尔运算符
-
!
非运算 -
-o
或运算or
-
-a
与运算and
逻辑运算符
-
&&
AND -
||
OR
字符串运算符
-
=
相等 -
!=
不相等 -
-z
字符串长度为0,返回true
-
-n
字符串长度不为0,返回true
-
str
字符串不为空,返回true
文件测试运算符
-
-b
检测文件是否块设备文件,是则返回true
-
-c
检测文件是否字符设备文件,是则返回true
-
-d
检测文件是否目录,是则返回true
-
-f
检测文件是否普通文件 (不是目录,也不是设备文件),是则返回true
-
-r
检测文件是否可读,是则返回true
-
-w
检测文件是否可写,是则返回true
-
-x
检测文件是否可执行,是则返回true
-
-s
检测文件是否为空(文件大小是否大于0),不为空则返回true
-
-e
检测文件(包括目录)是否存在,是则返回true
输出
开启转义
echo -e "Good~ \n"
显示结果定向至文件
echo "Hello World" > file
覆盖文件内容
echo "Hello World" >> file
追加内容
显示命令执行结果
echo `date`
格式化输出
使用
printf
命令
printf [format] [arguments...]
参数说明
-
-d
十进制整数 -
-s
字符串 -
-c
字符 -
-f
浮点数
printf "%-10s %-7s %3s %6s\n" Name Sex Age Score
printf "%-10s %-7s %3d %6.2f\n" Jack Male 27 82.3
printf "%-10s %-7s %3d %6.2f\n" Jennifer Female 25 91.62
printf "%-10s %-7s %3d %6.2f\n" Tom Male 56 96.372
输入
使用
read
命令
- 该命令一个一个词组接受输入的参数,每个词组需要使用
空格
进行分隔,以回车键
结束输入; - 如果输入词组个数小于需要的参数个数,则没赋值的参数为空;
- 如果输入词组个数大于需要的参数个数,则多出来的词组将作为整体为最后一个参数被接收。
参数说明
-
-p
输入提示文字 -
-n
输入字符长度限制,达到限制长度自动结束输入 -
-t
输入限时,单位是秒 -
-s
隐藏输入内容
read -p "Please input your password within 10 seconds: " -n 6 -t 10 -s password
echo -e "\nYour password is: $password"
流程控制
条件判断
if condition
then
command
...
fi
or
if condition
then
command1
else
command2
fi
or
if condition1
then
command1
elif condition2
then
command2
else
command3
fi
for 循环
for var in item ... itemN
do
command
...
done
while 循环
while condition
do
command
done
until 循环
until 循环执行一系列命令直至条件为true时停止
until condition
do
command
done
case
case value in
item1)
command1
;;
item2)
command2
;;
*)
commandN
;;
esac
break
跳出所有循环
continue
跳出当前循环
常用命令
清空终端
clear
创建文件
touch file
创建目录
mkdir dir
查看文件内容
cat file
显示指定工作目录下的内容
ls [-alrtAFR] [name...]
参数说明
-
-a
显示所有文件及目录 -
-A
同-a
,但不列出当前目录.
及 父目录..
-
-l
显示文件详细信息 -
-r
以相反次序显示 -
-t
按创建时间先后次序显示 -
-F
在文件后加符号,可执行文件加*
,目录加 `/`` -
-R
显示子目录下文件
改名、移动文件或目录
mv [options] src dest
或 mv [options] src... dir
参数说明
-
-i
询问是否覆盖 -
-f
不询问是否覆盖
复制文件或目录
cp [options] src dest
或 cp [options] src... dir
参数说明
-
-f
覆盖已经存在的目标文件而不给出提示 -
-i
和-f
相反,给出提示,要求用户回答y
或n
-
-r
若给出的源文件是一个目录文件,此时将复制该目录下所有的子目录和文件 -
-p
除内容外,还把修改时间和访问权限也复制到新文件中
删除文件或目录
rm [options] name
参数说明
-
-i
删除前逐一询问确认 -
-f
直接删除,无需确认 -
-r
删除目录及子目录所有文件
请求
curl [options...] <url>
参数说明
-
-o / --output FILE
写入文件而不是输出到终端 -
-x / --proxy [PROTOCOL://]HOST[:PORT]
使用代理 -
-k / --insecure
允许请求SSL网站而不校验证书 -
-b / --cookie STRING/FILE
从字符串或文件中读取cookie -
-D / --dump-header FILE
将接收到的header写入文件 -
-A / --user-agent STRING
发送User-Agent字符串到服务器 -
-e / --referer
伪造referer -
-d / --data DATA
post请求数据 -
-F / --form CONTENT
post请求提交表单,文件上传
curl -x "https.proxy=xxxxx:8080" -o main.html localhost/main.html
编辑文件
sed [-hnV] [-e<script>] [-f<script file>] [FILE]
参数说明
-
-e<script> / --expression=<script>
以选项中指定的script来处理输入的文本文件 -
-f<script file> / --file=<script file>
以选项中指定的script文件来处理输入的文本文件 -
-h / --help
显示帮助 -
-n / --quiet / --silent
仅显示script处理后的结果 -
-V / --version
显示版本信息
动作说明
-
a
新增,a 的后面可以接字符串,而这些字符串会在当前行的下一行出现 -
c
取代,c 的后面可以接字符串,这些字符串可以取代n1,n2之间的行 -
d
删除 -
i
插入,i 的后面可以接字符串,而这些字符串会在当前行的上一行出现 -
p
打印,将某个选择的数据打印出来;通常p
会与参数sed -n
一起运行 -
s
取代
替换标记
-
g
表示行内全面替换 -
p
表示打印行 -
w
表示把行写入一个文件 -
x
表示互换模版块中的文本和缓冲区的文本 -
y
表示把一个字符翻译为另外的字符,但是不用于正则表达式 -
\1
子串匹配标记 -
&
已匹配字符串标记
元字符集
-
^
匹配行开始,如/^test/
匹配所有以test
开头的行 -
$
匹配行结束,如/test$/
匹配所有以test
结尾的行 -
.
匹配一个非换行符的任意字符,如/a.b/
匹配a
后接一个任意字符,最后是b
的字符串 -
*
匹配0个或多个字符,如/*test/
匹配所有模版是一个或多个空格后紧跟test
的行 -
[]
匹配一个指定范围内的字符,如/[tT]est/
匹配test
和Test
-
[^]
匹配一个不在指定范围内的字符,如/[^A-SU-Z]est/
匹配不包含A-S
和U-Z
的一个字母开头,紧跟est
的行 -
\(...\)
匹配子串,保存匹配的字符,如s/\(love\)able/\1rs
,loveable
被替换成lovers
-
&
保存搜索字符,用来替换其他字符,如s/love/**&**/
,love
被替换成**love**
-
\<
匹配单词的开始,如/\<love/
匹配包含以love
开头的单词的行 -
\>
匹配单词的结束,如/love\>/
匹配包含以love
结尾的单词的行 -
x\{m\}
重复字符x
,m
次,如/0\{5\}/
匹配包含5
个0
的行 -
x\{m,\}
重复字符x
,至少m
次,如/0\{5,\}/
匹配至少包含5
个0
的行 -
x\{m,n\}
重复字符x
,至少m
次,不多于n
次,如/0\{5,10\}/
匹配5-10
个0
的行 -
\w\+
匹配每一个单词,如s/\w\+/[&]/g
为每个单词加上[]
sed -n '/\(versionCode\)/p'
sed -i "" "s/\">.*</\">${APP_NAME}</" ${FILE}
剪切字符串
如果指定
file
参数,则从文件的每一行剪切字节、字符和字段并将其写至标准输出如果不指定
file
参数,则读取标准输入必须指定
-b
-c
-f
之一
cut [-bn] [file]
cut [-c] [file]
cut [-df] [file]
参数说明
-
-b
以字节为单位进行分隔 -
-n
取消分隔多字节字符,仅和-b
标志一起使用 -
-c
以字符为单位进行分隔 -
-d
自定义分隔符,默认为制表符 -
-f
与-d
一起使用,指定显示哪个区域
echo 'username=Jack' | cut -d "=" -f2
截取字符串
-
${var#}
从左边开始,删除第一个匹配到的字符串的左边字符,保留右边字符 -
${var##}
从左边开始,删除最后一个匹配到的字符串的左边字符,保留右边字符 -
${var%}
从右边开始,删除第一个匹配到的字符串的右边字符,保留左边字符 -
${var%%}
从右边开始,删除最后一个匹配到的字符串的右边字符,保留左边字符
var="name=Jack"
echo ${var#*=}
例子
打印log到控制台并追加到文件
echo -e "gradle clean \n" | tee -a ${result}
判断参数个数
# 当参数个数不等于2时,输出 用法 到控制台
if [[ $# != 2 ]]
then
echo "Usage: $0 [src] [dest]"
fi
文件夹操作
# 当文件夹不存在时,创建文件夹; 当文件夹存在时,清空文件夹
if [[ ! -d ${folder} ]]
then
mkdir ${folder}
else
rm -rf ${folder}/*
fi
文件操作
# 当文件不为空时,拷贝文件
if [[ -s ${file} ]]
then
cp -f ${file} ${dest}
fi
定义函数
- download.sh
download() {
fileName=${1##*/}
curl -o ${fileName} $1
echo "${fileName}"
}
引入配置文件
- sh.config
MAIN_MODULE=app
APP_NAME=JL
OUTPUT=outputs
- test.sh
source ./sh.config
echo "main module is ${MAIN_MODULE}"
执行函数并将结果赋值
source ./download.sh
file=$(download ${url})
echo ${file}
使用 sed 匹配截取字符串
配置文件 config.xml
如下
<resources>
<string name="app_name">Demo</string>
</resources>
获取 app_name 的值,即 Demo
sed -n "/app_name/p" config.xml | sed "s/.*\"app_name\">\(.*\)<.*/\1/"