Shell 脚本

环境声明

#!/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 destmv [options] src... dir

参数说明

  • -i 询问是否覆盖
  • -f 不询问是否覆盖
复制文件或目录

cp [options] src destcp [options] src... dir

参数说明

  • -f 覆盖已经存在的目标文件而不给出提示
  • -i-f 相反,给出提示,要求用户回答 yn
  • -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/ 匹配 testTest
  • [^] 匹配一个不在指定范围内的字符,如 /[^A-SU-Z]est/ 匹配不包含 A-SU-Z 的一个字母开头,紧跟 est 的行
  • \(...\) 匹配子串,保存匹配的字符,如 s/\(love\)able/\1rsloveable 被替换成 lovers
  • & 保存搜索字符,用来替换其他字符,如 s/love/**&**/love 被替换成 **love**
  • \< 匹配单词的开始,如 /\<love/ 匹配包含以 love 开头的单词的行
  • \> 匹配单词的结束,如 /love\>/ 匹配包含以 love 结尾的单词的行
  • x\{m\} 重复字符 xm 次,如 /0\{5\}/ 匹配包含 50 的行
  • x\{m,\} 重复字符 x ,至少 m 次,如 /0\{5,\}/ 匹配至少包含 50 的行
  • x\{m,n\} 重复字符 x ,至少 m 次,不多于 n 次,如 /0\{5,10\}/ 匹配 5-100 的行
  • \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/"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 9,946评论 0 5
  • 第1章 小试牛刀 $ 是普通用户,# 表示管理员用户 root。 shebang:#!。sharp / hash ...
    巴喬書摘阅读 11,506评论 1 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,347评论 19 139
  • 菜鸟教程shell在线编辑器大目录整理: 1.第一个 Shell 脚本尝试 2.Shell 变量 3.Shell ...
    中酷男阅读 11,122评论 0 12
  • .bat脚本基本命令语法 目录 批处理的常见命令(未列举的命令还比较多,请查阅帮助信息) 1、REM 和 :: 2...
    庆庆庆庆庆阅读 12,557评论 1 19