Shell Scripts

Shell Scripts

简介

  • Shell脚本是由shell命令组成的执行文件,将一些命令整合到一个文件中,进行处理业务逻辑。脚本不用编译即可运行,它通过解释器解释运行,所以速度相对来说比较慢

第一个Shell脚本程序

#!/bin/bash
# 上面中的 #! 是一种约定标记, 它可以告诉系统这个脚本需要什么样的解释器来执行;
echo "Hello World!"

变量

定义变量

name="test"
number=100
# 创建普通变量
local name="test"
#创建只可函数体中使用的局部变量
unset name
# 删除变量

使用变量

echo $name
echo ${name}
# 推荐使用大括号版
  • Bash中的字符通过 ‘ 和 “ 分隔符来定义
  • 以 ‘ 定义的字符串为原义字符串,其中的变量不会被转义
  • 以 “ 定义的字符串会将变量值进行替换
foo=bar
echo "$foo"
# 打印 bar
echo '$foo'
# 打印 $foo

参数

参数处理 说明
$0 脚本名
19 脚本的参数.$1是第一个参数,依此类推
$@ 所有参数
$# 参数个数
$? 前一个命令的返回值
$$ 当前脚本的进程识别码
!! 完整的上一条命令,包括参数。例:sudo !!
$_ 上一条命令的最后一个参数

获取字符串长度

  • 在${}中使用“#”获取长度
echo ${#name}
# 输出为4

数组

定义数组

  • Bash支持一维数组, 不支持多维数组, 它的下标从0开始编号. 用下标[n] 获取数组元素
array_name=(value0 value1 value2 value3)
  • 也可以单独定义数组的各个分量,可以不使用连续的下标,而且下标的范围没有限制
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
  • 读取某个下标的元素
${array_name[index]}
  • 读取数组的全部元素
${array_name[*]}
#或
${array_name[@]}
  • 取得数组元素的个数
length=${#array_name[@]}
#或
length=${#array_name[*]}
  • 取得数组单个元素的长度
lengthn=${#array_name[n]}

运算符

算术运算符

  • 假定变量 a 为 10,变量 b 为 20
运算符 说明 举例
+ 加法 'expr a+b'
- 减法 'expr ab'
* 乘法 'expr ab'
/ 除法 'expr b/a'
% 取余 'expr ba'
= 赋值 a=$b
== 用于比较两个数字,相同则返回 true [ a==b ]
!= 用于比较两个数字,不相同则返回 true [ a!=b ]
++ 递增 let "a++" 或 ((a++))

其他

  • let
let Go=(1+3)*2
let Go=Python*256
let x++
let x+=2

关系运算符

  • 只支持数字,不支持字符串,除非字符串的值是数字
运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true [ aeqb ]
-ne 检测两个数是否不相等,不相等返回 true [ aneb ]
-gt 检测左边的数是否大于右边的,如果是,则返回 true [ agtb ]
-lt 检测左边的数是否小于右边的,如果是,则返回 true [ altb ]
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true [ ageb ]
-le 检测左边的数是否小于等于右边的,如果是,则返回 true [ aleb ]

字符串运算符

  • 假定变量 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语句

casein
模式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
#显示主目录下以 .bash 开头的文件
  • 数值处理
for ((初始值; 限制值; 赋值运算))
do
程序段
done
# 初始值:某个变量在循环中的起始值,直接以类似 i=1 设置好
# 限制值:当变量的值在这个限制值的范围内,就继续进行循环,例如 i<=100
# 赋值运算:每做一次循环时,变量也变化,例如i=i+1
  • 例如:
#!/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}"
# 进行从1累加到用户输入的数值的循环

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 !
!
# $10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数

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 # STDERR 重定向到 file
$ command 2> file # STDERR 追加到 file 文件末尾
  • 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null
$ command > /dev/null
  • /dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果.
$ command > /dev/null 2>&1
# 屏蔽 STDOUT 和 STDERR


如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   TNTksals  阅读(99)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示