持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
王志远,微医前端技术部
系列文目录
| 小节主题 | 文档 | 期待产出 | 补充 |
|---|---|---|---|
| Shell 的基本介绍、常用命令以及 Shell 的流程控制 | juejin.cn/post/714899… | ||
| Shell 中的数组应用、参数处理 | 本文 | ||
| Shell 的函数、模块化、公共函数库 | |||
| Shell 周边:语言特殊点/调试 Debug 方案/vscode 对 shell 的支持 |
Shell 中的数组应用、参数处理和函数的应用
shell 之语句
- 顺序
- 测试:退出与退出状态、测试命令 test
- 分支:if-then
- 循环:for/while/do-while
测试命令(学习分支语句的前提)
参考文档:
状态:$? 和 exit
根据程序是否正常执行(程序退出的状态)进行判断
- exit:手动退出 shell 的命令
- exit 10 返回 10 给 shell,返回值非 0 为不正常退出
- $? 用于判读昂当前 shell 前一个进程是否正常退出(非 0 为不正常退出)
命令:test
tesh 命令可以用于检查文件或者比较值,可用于如下功能(可以用man test查看更具体的命令)
- 整数比较测试
- 字符串测试
- 文件测试
test 测试语句可以简化为[]符号,而[]符号还有扩展写法[[]] ,支持 &&、||、<、>(推荐使用[[]])
字符串测试
两个字符串是否相等:[str1 = str2] 和 [str1 != str2]
#!/bin/bash
str1='a'
str2='a'
if [ $str1 = $str2 ]; then
echo '等于'
elif [ $str1 != $str2 ]; then
echo '不等于'
fi
读取字符串长度是否是 0(空字符串):-z
#!/bin/bash
str1='a'
str2=''
if [ -z $str1 ]; then
echo 'str1 为空字符串'
else
echo 'str1 不为空字符串'
fi
if [ -z $str2 ]; then
echo 'str2 为空字符串'
else
echo 'str2 不为空字符串'
fi
整数比较测试
| 功能 | []中的符号 | [[]]中的支持 |
|---|---|---|
| 等于 | -eq 和 = 均支持 | = |
| 大于等于 | -ge | 暂无 |
| 大于 | -gt | > |
| 小于等于 | -le | 暂无 |
| 小于 | -lt | < |
| 不等于 | -ne | != |
#!/bin/bash
a=1
b=2
# if [ $a = $b ]; then
if [ $a -eq $b ]; then
echo 'a 等于 b'
elif [ $a -ge $b ]; then
echo 'a 大于等于 b'
elif [ $a -gt $b ]; then
echo 'a 大于 b'
elif [ $a -le $b ]; then
echo 'a 小于等于 b'
elif [ $a -lt $b ]; then
echo 'a 小于 b'
elif [ $a -ne $b ]; then
echo 'a 不等于 b'
fi
if [[ $a = $b ]]; then
echo 'a 等于 b'
# elif [[ $a >= $b ]]; then
# echo 'a 大于等于 b'
elif [[ $a > $b ]]; then
echo 'a 大于 b'
# elif [[ $a <= $b ]]; then
# echo 'a 小于等于 b'
elif [[ $a < $b ]]; then
echo 'a 小于 b'
elif [[ $a != $b ]]; then
echo 'a 不等于 b'
fi
文件测试
| 功能 | 符号 | 例子 |
|---|---|---|
| -b | ||
| -e | 路径存在,不区分文件和目录 | test -e [路径] 或 [ -e [路径]] |
| -d | 目录是否存在 | test -d [路径] 或 [ -d [路径]] |
| -f | 文件是否存在 | test -f [路径] 或 [ -f [路径]] |
| -x | 文件是否可执行 |
分支语句
- 基础 if
- if-else
- if-elif
- 嵌套 if
- case 语句
基本用法:基础 if
- 测试语句
- 命令返回值
if [ 测试条件成立 || 命令返回值为 0 ]; then
相关行为
fi # 结束
实例
if [ $UID = 0 ]; then
echo " root user "
fi
if [ pwd ]; then
echo " root user "
fi
基本用法:if-else
if [ 测试条件成立 || 命令返回值为 0 ]; then
相关行为
elif
相关行为
fi # 结束
实例
#!/bin/bash
if [ $UID = 0 ]; then
echo " root user "
elif
echo " $UID user "
fi
基本用法:if-elif-else
if [ 测试条件成立 || 命令返回值为 0 ]; then
相关行为
elif [ 测试条件成立 || 命令返回值为 0 ]; then
相关行为
elif
相关行为
fi # 结束
实例
#!/bin/bash
if [ $UID = 0 ]; then
echo " root user "
elif [ $UID = 501 ]; then
echo " wangzy user "
else
echo " $UID user "
fi
基本用法:嵌套 if
#!/bin/bash
if [ 测试条件成立 || 命令返回值为 0 ]; then
if [ 测试条件成立 || 命令返回值为 0 ]; then
相关行为
else
相关行为
fi # 结束
else
相关行为
fi # 结束
实例实现:先判断是不是王志远账户,是则再执行对应文件
#!/bin/bash
if [ $UID = 0 ]; then
echo " root user "
elif [ $UID = 501 ]; then
if [ -x /Users/wzyan/Documents/selfspace/kkb-down/demo/if/index.sh ]; then
$(pwd)/index.sh
else
echo " wangzy user error $(pwd)"
fi
else
if [ $(pwd) = "/Users/wzyan/Documents/selfspace/kkb-down/demo/if" ]; then
echo " wangzy user path"
else
echo " wangzy user error $(pwd)"
fi
fi
case 语句
case "$变量" in
"情况 1" )
命令...;;
"情况 2" )
命令...;;
* )
命令...;;
esac
实例实现:先判断是不是王志远账户,是则再执行对应文件
#!/bin/bash
case "$1" in
"start" | "restart")
echo $0 starting...
;;
"stop")
echo $0 stoping...
;;
*)
echo "$0 传参错误 {start|stop|restart|reload}"
;;
esac
循环语句
- for
- c 语言风格的 for
- while
- util
- 嵌套循环
- 使用关键字 break 和 continue
for 循环
注意:
- 当使用反引号或者$()执行命令时,其结果会被当作列表处理
- 列表中包含多个变量,变量间用空格分隔
- 对文本处理时,要用文本查看命令取出文本内容,默认装处理,如果出现空格就会当成多行处理
for 参数 in 列表
do 执行的命令
done #封闭一个循环
实例实现:遍历列表输出
#!/bin/bash
for i in {1..9}
do zzxzxxxzzzzzzzzzzzzzzzzzzzzzzzzzzzxxxxxecho hello; echo $i
done #封闭一个循环
# 读取指定目录下的所有可执行 sh 文件
for sc_name in /etc/profile.d/*.sh
do echo $sc_name; echo $i
done #封闭一个循环
实例实现:读取命令结果进行取出所有 mp3 文件的文件名(basename [文件路径] [文件后缀])
#!/bin/bash
for filename in `ls *.mp3`
do
mv $filename $(basename $filename .mp3).mp4
done
c 语言风格的 for
for((变量初始化;循环判断条件;变量变化))
do
循环执行命令
done
实例实现:输出 1-10
#!/bin/bash
for((i=1;i<=10;i++))
do
echo $i
done
while
特点:直到输入为非 0 才中止
while [test 测试为假时中止]
do
命令
done
实例实现:输出 1-10
#!/bin/bash
a=1 # 小于 10
while [ $a -lt 10 ]
do
((a++)); echo $a;
done
实现死循环
while :; do echo ;done
until
特点:与 while 相反,直到输入为 0 才中止
until [test 测试为真时中止]
do
命令
done
实例实现:输出 1-10
#!/bin/bash
while []
do
命令
done
嵌套循环
找出/etc/profile.d 目录下所有可执行文件
for sc_name in /etc/profile.d/*.sh
do
echo $sc_name
done
找出/etc/profile.d 目录下所有可执行文件并执行
for sc_name in /Users/wzyan/Documents/selfspace/kkb-down/demo/for/test-x/*.sh; do
if [ -x $sc_name ]; then
. $sc_name
fi
done
使用关键字 break 和 continue
找出/etc/profile.d 目录下所有可执行文件并执行
for num in {1..9}
do
echo $num
done
实战:处理命令行参数
- 命令行参数可以使用2..{n}进行读取
- $0 代表脚本名称
- @代表所有位置参数
- $#代表位置参数的数量
for pos in $*; do
if [ "$pos" = "help" ]; then
echo $pos
fi
done