首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >shell 运算符、控制结构和函数

shell 运算符、控制结构和函数

原创
作者头像
用户12619466
修改2026-07-17 23:05:15
修改2026-07-17 23:05:15
140
举报

shell运算符<span id='operator'/>

  • 原始 bash 不支持简单的数学运算符,但可以通过 awkexpr 实现,expr 命令常用,也可使用 bc(需安装)
代码语言:shell
复制
val=`expr 2 + 2` # 运算符要和表达式间要有空格,不能是 expr 2+2,写在 (()) 中不受此限制
# 假设 a=10,b=20
`expr $a + $b` # 30
`expr $a - $b` # -10
`expr $a \* $b` # 200
`expr $a / $b` # 2
`expr $a % $b` # 取余 0
a=$b # 把b的值赋给a
[ $a == $b ] # 数值比较 false
[ $a != $b ] # true

echo "2 + 3" | bc # 输出 5
echo "10 / 3" | bc # 输出: 3 除法默认只返回整数部分
echo "scale=4; 22 / 7" | bc # 输出: 3.1428  scale控制精度
# 进制转换,ibase:输入数字的进制,obase:输出数字的进制
echo "ibase=16; FF" | bc # 输出:255

条件表达式要放在方括号中,并且要有空格[$a==$b]是错误的

  • 关系、布尔、逻辑运算符
代码语言:shell
复制
[ $a -eq $b ] # a==b equal
[ $a -ne $b ] # a!=b not equal
[ $a -ge $b ] # a≥b great equal
[ $a -le $b ] # a≤b less equal
[ $a -gt $b ] # a>b great than
[ $a -lt $b ] # a<b less than

[ ! false ] # ! 非运算
[ $a -lt $b -a $b -gt $a ] # -a 与运算 and
[ $a -lt $b -o $b -gt $a ] # -o 或运算 or
# 优先级:! > -a > -o

[ $a -lt $b && $b -gt $a ] # && 逻辑的and
[ $a -lt $b || $b -gt $a ] # || 逻辑的or
  • 字符串运算符
代码语言:shell
复制
# a="abc", b="efg"
[ $a = $b ] # a==b 
[ $a != $b ] # a!=b
[ -z $a ] # 字符串长度为0返回true,a.size()==0
[ -n $a ] # 字符串长度不为0返回true,a.size()!=0
[ $a ] # 字符串不为空返回true a.isNotEmpty()
  • 文件测试运算符
代码语言:shell
复制
[ -b $file ] # file是块设备文件返回true
[ -c $file ] # file是字符设备文件返回true
[ -d $file ] # file是目录返回true
[ -f $file ] # file是普通文件返回true(既不是目录也不是设备文件)
[ -g $file ] # file设置了SGID位返回true
[ -k $file ] # file设置了粘着位(Sticky Bit)返回true
[ -p $file ] # file是有名管道返回true
[ -u $file ] # file设置了SUID位返回true
[ -r $file ] # file可读返回true
[ -w $file ] # file可写返回true
[ -x $file ] # file可执行返回true
[ -s $file ] # file为不为空返回true(文件大小大于0)
[ -e $file ] # file存在返回true(包括目录)
[ -S $file ] # file是socket文件返回true
[ -L $file ] # file存在并且是一个符号连接返回true
[ -t $fd   ] # 检查文件描述符 fd 是否连接到一个终端
[ -v $var  ] # 检查变量 var 是否设置(Bash 4.2+)
  • echo 命令(会自动换行)
    • 显示普通字符:echo "It is a test",可省略双引号 echo It is a test
    • 显示转义字符:echo "\"It is a test\""
    • 显示变量:echo "$var_name It is a test"
    • 显示换行:echo -e "OK! \n It is a test" # -e 开启转义
    • 显示不换行:echo -n "OK! \n It is a test" # -n 不换行
    • 显示结果定向至文件:echo "It is a test" > myfile
    • 显示命令执行结果:echo `date`
  • printf 命令(不自动换行):printf format-string [args...]
代码语言:shell
复制
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg  
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876

%-10s:字符串,宽度为10个字符,-表示左对齐,没有则右对齐

%d:十进制整数

%-4.2f:浮点数,.2 表示保留两位小数

%c:字符

%x:十六进制数

%o:八进制数

%b:二进制数

%e:科学计数法表示的浮点数

  • test 命令:用于检查某个条件是否成立,对数值、字符和文件进行检测
代码语言:shell
复制
a=100
b=200
if test $[a] -eq $[b]
then 
    echo '两数相等!'
else
    echo '两数不相等!'
fi
# 输出:两数不相等! []执行基本的算数运算:res=$[a+b] res为300

控制流<span id='control-flow'/>

if 语句

  • 一个条件后就要跟一个 then,以 fi 结束(if 的倒序)
    • 条件写在 [] 中用 -gt,-lt,-eq,例如:[ $a -gt $b ]
    • 条件写在 (()) 中可直接用 >,<,=,例如:(( $a > $b ))
代码语言:shell
复制
# 多行写法
if condition; then
     command1
else
     commandN
fi
# 一行写法
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo 'true'; fi

if [ $a -gt $b ]
then
    echo 'a > b'
elif [ $a -eq $b ]
then
    echo 'a = b'
else
    echo 'a < b'
fi
  • 其中 condition 的“真/假”由命令的退出状态码(exit status)决定:退出码为 0 → 条件为真(true);退出码非 0 → 条件为假(false)if 语句的几种形式
  • if [ ... ]:POSIX 兼容的测试命令(等价于 test
    • [ 实际上是 test 命令(/usr/bin/[ 或内置命令),前后必须有空格。] 不是独立命令,它是 [ 命令的语法要求:最后一个参数必须是 ]
    • 不支持逻辑运算符 &&||[ ] 内部直接使用(需用 -a-o,但已过时)
    • 变量建议加双引号,防止空值或含空格时报错。
    • 字符串比较使用 =, !=,没有 <, >, =~ 等运算符,数值使用 -eq, -ne 等,逻辑运算:-a, -o, !
  • if [[ ... ]]:Bash/Zsh 的增强测试(推荐在 Bash 中使用),是 Bash 内置语法,不是命令,更安全、功能更强。支持:
    • 通配符匹配:== 可用于模式匹配,如 if [[ $var == file*.txt ]]; if [[ $var == $pattern ]]file*.txt, $pattern 不能加双引号,会阻止通配符展开
    • 正则表达式:[[ $str =~ ^[0-9]+$ ]]
    • 逻辑运算符:&&||!
    • 无需对变量加双引号(但仍建议加)
    • 不会因分词或路径展开出错
    • 不兼容 POSIX(/bin/sh 在 Debian/Ubuntu 下是 dash,不支持)
    • 对于字符串的比较使用 ==/=, !=, >, <, =~,数值比较使用 -ne, -eq, -ge 等,逻辑运算:!, &&, ||
  • if (( ... )):整数算术条件判断
    • 专门用于整数的运算和比较
    • 变量无需加 $(当然加了也可以)
    • 支持 ==!=<<=>>=&&||!、位运算等
    • 表达式结果非 0 → true;结果为 0 → false
    • 仅适用于 Bash、Zsh 等,非 POSIX
  • if command; then:以命令的退出状态作为条件
    • 任何命令都可以作为条件!
    • if command:命令成功(exit 0)
    • if ! command:命令失败(exit ≠ 0)
    • if command1 && command2:两个都成功
    • if command1 || command2:至少一个成功
    • 这是 if 最本质的用法,其他 [ ][[ ]](( )) 都是特例。

for 循环

代码语言:shell
复制
# 多行写法
for var in item1 item2 ... itemN
do
    command1
    command2
    ...
done

# 一行写法
for var in item1 item2 ... itemN; do command1; command2; ...; done

while、until 循环

代码语言:shell
复制
while [until] [ $a -gt $b ] # : 冒号用于无限循环,也可使用 true,for (( ; ; ))
do 
    command
done

while read FILM # read 读取键盘信息,按<Ctrl-D>结束
do
    echo "FILM = $FILM"
done

case 语句

  • 每个 case 分支以 ) 开始,用 ;; 表示 break,执行结束,esac 作为结束标记(case 的倒序)
代码语言:shell
复制
case $var in 
var1|var2|var3|...)
    command1
    ...
    ;;
varN)
    command2
    ...
    ;;
*) # 以上未匹配时捕获
    command3
    ...
    ;;
esac
  • 跳出循环
    • break:跳出所有循环(终止执行后面的所有循环)
    • continue:跳出当前循环

shell 函数

代码语言:shell
复制
# 函数定义
# 通过 $1 $2 ... $n 获取参数,当 n>=10 时,需使用 ${n} 获取参数
[ function ] fun (){
    action;
    [return int;]
}

# 函数调用 只需用函数名 fun
fun arg1 agr2 ... agrN
  • function关键字是可选的
  • 不加return则以最后一条命令的运行结果作为返回值
  • 显示加return返回值只能是数值,介于(0-255)
  • 如果return值超出255,直接使用echo输出而不是用return
  • 函数返回值在调用函数后通过$?来获得
  • 函数必须在使用前定义,一般放于脚本开始部分

欢迎大家关注【扶锐随笔】

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • shell运算符<span id='operator'/>
  • 控制流<span id='control-flow'/>
    • if 语句
    • for 循环
    • while、until 循环
    • case 语句
    • shell 函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档