Shell Scripts
简介
- Shell脚本是由shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑。脚本不用编译即可运行,它通过解释器解释运行,所以速度相对来说比较慢
第一个Shell脚本程序
| #!/bin/bash |
| |
| |
| echo "Hello World!" |
变量
定义变量
| name="test" |
| number=100 |
| |
| |
| local name="test" |
| |
| |
| unset name |
| |
使用变量
- Bash中的字符通过 ‘ 和 “ 分隔符来定义
- 以 ‘ 定义的字符串为原义字符串,其中的变量不会被转义
- 以 “ 定义的字符串会将变量值进行替换
| foo=bar |
| echo "$foo" |
| |
| echo '$foo' |
| |
参数
参数处理 |
说明 |
$0 |
脚本名 |
1到9 |
脚本的参数.$1是第一个参数,依此类推 |
$@ |
所有参数 |
$# |
参数个数 |
$? |
前一个命令的返回值 |
$$ |
当前脚本的进程识别码 |
!! |
完整的上一条命令,包括参数。例:sudo !! |
$_ |
上一条命令的最后一个参数 |
获取字符串长度
数组
定义数组
- Bash支持一维数组, 不支持多维数组, 它的下标从0开始编号. 用下标[n] 获取数组元素
| array_name=(value0 value1 value2 value3) |
- 也可以单独定义数组的各个分量,可以不使用连续的下标,而且下标的范围没有限制
| array_name[0]=value0 |
| array_name[1]=value1 |
| array_name[2]=value2 |
| ${array_name[*]} |
| |
| ${array_name[@]} |
| length=${#array_name[@]} |
| |
| length=${#array_name[*]} |
| lengthn=${#array_name[n]} |
运算符
算术运算符
运算符 |
说明 |
举例 |
+ |
加法 |
'expr a+b' |
- |
减法 |
'expr a−b' |
* |
乘法 |
'expr a∗b' |
/ |
除法 |
'expr b/a' |
% |
取余 |
'expr ba' |
= |
赋值 |
a=$b |
== |
用于比较两个数字,相同则返回 true |
[ a==b ] |
!= |
用于比较两个数字,不相同则返回 true |
[ a!=b ] |
++ |
递增 |
let "a++" 或 ((a++)) |
其他
| let Go=(1+3)*2 |
| let Go=Python*256 |
| let x++ |
| let x+=2 |
关系运算符
运算符 |
说明 |
举例 |
-eq |
检测两个数是否相等,相等返回 true |
[ a−eqb ] |
-ne |
检测两个数是否不相等,不相等返回 true |
[ a−neb ] |
-gt |
检测左边的数是否大于右边的,如果是,则返回 true |
[ a−gtb ] |
-lt |
检测左边的数是否小于右边的,如果是,则返回 true |
[ a−ltb ] |
-ge |
检测左边的数是否大于等于右边的,如果是,则返回 true |
[ a−geb ] |
-le |
检测左边的数是否小于等于右边的,如果是,则返回 true |
[ a−leb ] |
字符串运算符
- 假定变量 a 为 "abc",变量 b 为 "efg"
运算符 |
说明 |
举例 |
= |
检测两个字符串是否相等,相等返回 true |
[ a=b ] |
!= |
检测两个字符串是否不相等,不相等返回 true |
[ a!=b ] |
-z |
检测字符串长度是否为0,为0返回 true |
[ -z $a ] |
-n |
检测字符串长度是否不为 0,不为 0 返回 true |
[ -n "$a" ] |
|检测字符串是否为空,不为空返回true|[a ] |
|
|
- 在Bash中进行比较时,尽量使用双方括号[[ ]]而不是方括号[ ],这样会降低犯错的几率,尽管这样并不能兼容sh
条件语句
If语句
- if [ 表达式 ] then 语句 fi
- if [ 表达式 ] then 语句 else 语句 fi
- if [ 表达式] then 语句 elif[ 表达式 ] then 语句 elif[ 表达式 ] then 语句 …… fi
| a=10 |
| b=20 |
| if [ $a == $b ] |
| then |
| echo "a is equal to b" |
| else |
| echo "a is not equal to b" |
| fi |
case ... esac语句
| case 值 in |
| 模式1) |
| command1 |
| command2 |
| command3 |
| ;; |
| 模式2) |
| command1 |
| command2 |
| command3 |
| ;; |
| *) |
| command1 |
| command2 |
| command3 |
| ;; |
| esac |
- 取值后面必须为关键字 in,每一模式必须以右括号结束
- 取值可以为变量或常数
- 如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令
for循环
| for 变量 in 列表 |
| do |
| command1 |
| command2 |
| ... |
| commandN |
| done |
| |
| |
| |
| for loop in 1 2 3 4 5 |
| do |
| echo "The value is: $loop" |
| done |
| |
| |
| #!/bin/bash |
| for FILE in $HOME/.bash* |
| do |
| echo $FILE |
| done |
| |
| |
| for ((初始值; 限制值; 赋值运算)) |
| do |
| 程序段 |
| done |
| |
| |
| |
| |
| #!/bin/bash |
| |
| read -p "Please input a number, I will count for 1+2+...+your_input: " nu |
| s=0 |
| for ((i=1; i<=${nu}; i=i+1)) |
| do |
| s=$((${s}+${i})) |
| done |
| echo "The result of '1+2+3+...+${nu}' is ==> ${s}" |
| |
| |
while循环
一般格式:
| while condition |
| do |
| command |
| done |
函数
Shell函数必须先定义后使用,定义如下,
| function_name () |
| { |
| list of commands |
| [ return value ] |
| } |
- 调用函数只需要给出函数名,不需要加括号
- 函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值
- Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败
- 函数的参数可以通过 $n 得到,如:
| funWithParam(){ |
| echo "第一个参数为 $1 !" |
| echo "第二个参数为 $2 !" |
| echo "第十个参数为 $10 !" |
| echo "第十个参数为 ${10} !" |
| echo "第十一个参数为 ${11} !" |
| echo "参数总数有 $# 个!" |
| echo "作为一个字符串输出所有参数 $* !" |
| } |
| funWithParam 1 2 3 4 5 6 7 8 9 34 73 |
| |
| :<<! |
| 第一个参数为 1 ! |
| 第二个参数为 2 ! |
| 第十个参数为 10 ! |
| 第十个参数为 34 ! |
| 第十一个参数为 73 ! |
| 参数总数有 11 个! |
| 作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 ! |
| ! |
| |
Shell的文件包含
- Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本
| . filename |
| |
| source filename |
- 两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格
- 被包含脚本不需要有执行权限
重定向
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(STDIN):STDIN 的文件描述符为0,Unix程序默认从STDIN读取数据
- 标准输出文件(STDOUT):STDOUT 的文件描述符为1,Unix程序默认向STDOUT输出数据(返回输出值)
- 标准错误文件(STDERR):STDERR 的文件描述符为2,Unix程序会向STDERR流中写入错误信息
| $ command 2> file |
| $ command 2> file |
- 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null
- /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果.
| $ command > /dev/null 2>&1 |
| |
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现