文章目录

  • Shell 中 ()、(())、[]、{} 的用法详解
    • 一、先明确:四类符号的核心功能定位
    • 二、逐个拆解:用法、示例与避坑点
      • 1. `()`:子 Shell 执行,隔离环境
        • 核心用法1:子 Shell 执行命令,隔离变量
        • 核心用法2:`$()` 捕获命令输出(命令替换)
      • 2. `(())`:算术扩展,专注数值计算与比较
        • 核心用法1:整数计算(替代 `expr`)
        • 核心用法2:算术条件判断(替代 `[ ]` 中的 `-gt`/`-lt`)
      • 3. `[]`:条件测试(等价于 `test` 命令)
        • 先明确:`[]` 与 `test` 的等价性
        • 核心用法1:数值比较(需用 `-gt`/`-lt` 等符号)
        • 核心用法2:字符串比较
        • 核心用法3:文件属性判断(常用场景)
        • 避坑点:`[]` 的语法严格性
      • 4. `{}`:变量范围界定 + 代码块
        • 核心用法1:变量范围界定(最常用)
        • 核心用法2:代码块(批量执行命令,不启动子 Shell)
    • 三、总结:四类符号的“场景选择指南”

Shell 中 ()、(())、[]、{} 的用法详解

在 Shell 脚本中,()(())[]{} 是功能差异极大的符号,分别对应“子 Shell 执行”“算术计算”“条件判断”“变量范围界定”等核心场景。本文结合你之前关注的字符串操作和运算符,系统拆解这四类符号的用法,帮你彻底理清适用边界,避免混淆。

一、先明确:四类符号的核心功能定位

首先用一张表区分四类符号的“本质用途”,避免从语法细节陷入混乱:

符号核心功能典型使用场景依赖环境
()启动子 Shell 执行命令,不影响当前 Shell临时执行命令、隔离变量作用域所有 Shell(bash、sh 等)
(())算术扩展,用于数值计算和比较整数运算、算术条件判断(如 a > bBash 专属(不兼容 sh)
[]条件测试(等价于 test 命令)字符串比较、数值比较、文件属性判断所有 Shell
{}1. 变量范围界定;2. 代码块(需加 ;明确变量边界(如 ${var}123)、批量执行命令所有 Shell

二、逐个拆解:用法、示例与避坑点

1. ():子 Shell 执行,隔离环境

() 会启动一个独立的子 Shell 进程,在其中执行括号内的命令,特点是:

  • 子 Shell 中的变量、环境变量修改不影响当前 Shell(隔离作用域);
  • 命令执行结果可通过 $() 捕获(即“命令替换”,等价于反撇号 `)。
核心用法1:子 Shell 执行命令,隔离变量
# 当前 Shell 定义变量 a=10
a=10
echo "当前 Shell 初始 a:$a"  # 输出:当前 Shell 初始 a:10# 用 () 启动子 Shell,修改 a 的值
(a=20; echo "子 Shell 中 a:$a")  # 输出:子 Shell 中 a:20# 回到当前 Shell,查看 a 的值(未被修改)
echo "当前 Shell 最终 a:$a"  # 输出:当前 Shell 最终 a:10

避坑点:若想让子 Shell 的变量影响当前 Shell,需用管道或重定向(如 (a=20; echo $a) > temp.txt,再从文件读取),但直接赋值无效。

核心用法2:$() 捕获命令输出(命令替换)

这是 () 最常用的场景,替代反撇号 ` 实现“执行命令并获取结果”,支持嵌套:

# 场景1:获取当前目录下的文件数(ls 结果通过 wc -l 统计)
file_count=$(ls -l | wc -l)
echo "当前目录文件数:$file_count"# 场景2:嵌套命令替换(先找 python 路径,再查看路径属性)
python_attr=$(ls -l $(which python))
echo "Python 命令属性:$python_attr"

优势:反撇号 ` 不支持嵌套(如 `ls `which python` 报错),而 $() 完全支持,可读性更强。

2. (()):算术扩展,专注数值计算与比较

(()) 是 Bash 专属的“算术扩展”语法,专门处理整数运算和算术条件判断,特点是:

  • 支持所有算术运算符(+-*/% 等),无需转义 *(区别于 expr);
  • 支持算术比较(><>=<===!=);
  • 变量引用可省略 $(如 ((a + b)) 而非 (( $a + $b )))。
核心用法1:整数计算(替代 expr
a=23
b=24# 1. 基础运算:直接计算并输出
echo "a + b = $((a + b))"  # 输出:a + b = 47
echo "a * b = $((a * b))"  # 输出:a * b = 552(无需转义 *)# 2. 运算结果赋值给变量
c=$((a * b + 10))  # 23*24 +10 = 552+10=562
echo "c = $c"  # 输出:c = 562# 3. 自增/自减(类似其他编程语言)
((a++))  # a 自增 1(从23变为24)
echo "a 自增后:$a"  # 输出:a 自增后:24

在这里插入图片描述
在这里插入图片描述

核心用法2:算术条件判断(替代 [ ] 中的 -gt/-lt

if 语句中,(()) 可直接判断数值大小,语法比 [ ] 更简洁(无需记 -gt/-lt 等符号):

age=25
if ((age >= 18 && age <= 30)); thenecho "年龄在 18-30 之间(青年)"  # 输出:年龄在 18-30 之间(青年)
fi# 对比 [ ] 的写法(需用 -ge/-le 和 -a)
if [ $age -ge 18 -a $age -le 30 ]; thenecho "年龄在 18-30 之间(青年)"
fi

避坑点(()) 仅支持整数,不支持小数(如 ((3.14 > 3)) 会报错);且不支持字符串比较(如 (( "a" == "b" )) 报错)。

在这里插入图片描述

3. []:条件测试(等价于 test 命令)

[]test 命令的简写形式,核心功能是条件测试,包括“字符串比较”“数值比较”“文件属性判断”三类场景,返回值为“0(成立)”或“非0(不成立)”,需结合 if/&&/|| 使用。

先明确:[]test 的等价性
# 以下两条命令完全等价(判断文件 /etc/passwd 是否存在)
test -f /etc/passwd && echo "文件存在"
[ -f /etc/passwd ] && echo "文件存在"  # 更常用的写法
核心用法1:数值比较(需用 -gt/-lt 等符号)

[] 中不能直接用 >/<(会被当作重定向符号),必须用专用的数值比较运算符:

运算符含义示例(判断 a=23,b=24)
-eq等于[ $a -eq $b ] → 不成立(23≠24)
-ne不等于[ $a -ne $b ] → 成立(23≠24)
-gt大于[ $a -gt $b ] → 不成立(23<24)
-lt小于[ $a -lt $b ] → 成立(23<24)
-ge大于等于[ $a -ge $b ] → 不成立
-le小于等于[ $a -le $b ] → 成立

示例:

a=23
b=24
if [ $a -lt $b ]; thenecho "$a 小于 $b"  # 输出:23 小于 24
fi
核心用法2:字符串比较

[] 中字符串比较需注意“是否加双引号”(避免空值导致语法错误):

运算符含义示例(str1=“abc”,str2=“abd”)
==/=等于[ "$str1" == "$str2" ] → 不成立
!=不等于[ "$str1" != "$str2" ] → 成立
-z字符串长度为0(空)[ -z "$str1" ] → 不成立(str1非空)
-n字符串长度非0(非空)[ -n "$str1" ] → 成立(str1非空)

示例:

username="admin"
# 判断用户名是否为 admin(加双引号避免 username 为空时报错)
if [ "$username" == "admin" ]; thenecho "欢迎管理员登录"  # 输出:欢迎管理员登录
fi# 判断字符串是否为空
empty_str=""
if [ -z "$empty_str" ]; thenecho "empty_str 是空字符串"  # 输出:empty_str 是空字符串
fi
核心用法3:文件属性判断(常用场景)

[] 支持判断文件是否存在、是否为目录/普通文件等,是脚本中“文件操作前校验”的核心语法:

运算符含义示例(判断 /etc/passwd)
-f是否为普通文件[ -f /etc/passwd ] → 成立(是普通文件)
-d是否为目录[ -d /etc/passwd ] → 不成立(非目录)
-e文件/目录是否存在[ -e /etc/passwd ] → 成立(存在)
-r是否有读权限[ -r /etc/passwd ] → 成立(root有读权限)
-w是否有写权限[ -w /etc/passwd ] → 成立(root有写权限)
-x是否有执行权限[ -x /etc/passwd ] → 不成立(无执行权限)

示例:

file="/etc/passwd"
if [ -f "$file" ] && [ -r "$file" ]; thenecho "$file 是普通文件且有读权限"  # 输出:/etc/passwd 是普通文件且有读权限
fi
避坑点:[] 的语法严格性
  • 括号内前后必须有空格(如 [ -f /etc/passwd ] 正确,[-f /etc/passwd] 报错);
  • 变量必须加双引号(如 [ "$username" == "admin" ],避免变量为空时变成 [ == "admin" ] 语法错误);
  • 不能直接用 &&/||(需用 -a/-o 表示“与”/“或”,如 [ -f "$file" -a -r "$file" ])。

4. {}:变量范围界定 + 代码块

{} 在 Shell 中有两种核心用法,需根据场景区分:

核心用法1:变量范围界定(最常用)

当变量名后紧跟其他字符(如数字、字母)时,用 {} 明确变量边界,避免 Shell 误判变量名:

product="Python"
# 需求:输出 "Python3.11"(变量 product 后紧跟 3.11)
# 错误:Shell 会把 $product3.11 当作一个变量(未定义,输出空)
echo "$product3.11"  # 输出:(空值)# 正确:用 {} 明确变量是 product,后续 3.11 是普通字符
echo "${product}3.11"  # 输出:Python3.11

延伸:结合字符串操作(你之前关注的内容),${} 还支持“子串提取”“长度计算”:

str="this is zjl"
echo "${#str}"        # 计算长度:输出 10
echo "${str:5:2}"     # 提取子串:从索引5开始取2个字符,输出 "is"
核心用法2:代码块(批量执行命令,不启动子 Shell)

{} 可包裹多个命令,作为“代码块”执行,特点是:

  • 不启动子 Shell,命令在当前 Shell 执行(变量修改会影响当前 Shell);
  • 语法严格:括号内最后一条命令必须加 ;,且 { 后必须有空格。

示例:

# 用 {} 执行代码块,修改当前 Shell 的变量
a=10
{a=20echo "代码块中 a:$a"  # 输出:代码块中 a:20b=30  # 定义变量 b,在当前 Shell 生效
}  # 注意:若代码块在一行,需写成 { a=20; echo $a; }# 回到当前 Shell,查看变量(a 和 b 都被修改/定义)
echo "当前 Shell a:$a"  # 输出:当前 Shell a:20
echo "当前 Shell b:$b"  # 输出:当前 Shell b:30

对比 ()() 启动子 Shell,变量修改不影响当前;{} 不启动子 Shell,变量修改影响当前——这是两者作为代码块的核心区别。

三、总结:四类符号的“场景选择指南”

最后用一张表帮你快速决策“什么场景用什么符号”,避免再混淆:

需求场景推荐符号示例
临时执行命令,隔离变量()(a=20; echo $a)(a 不影响当前 Shell)
捕获命令输出(命令替换)$()`file_count=$(ls -l
整数计算/算术比较(())if ((age >= 18)); then ...
条件测试(字符串/数值/文件)[][ -f /etc/passwd ][ "$str" == "abc" ]
明确变量边界/字符串操作${}${product}3.11${#str}
批量执行命令,影响当前 Shell{}{ a=20; echo $a; }(a 影响当前 Shell)

掌握这四类符号后,你可以更灵活地处理 Shell 脚本中的“环境隔离”“数值计算”“条件判断”和“变量操作”,结合之前的字符串和运算符知识,就能写出逻辑清晰、不易出错的脚本了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/94805.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/94805.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/94805.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发避坑指南(41):Vue3 提示框proxy.$modal.msgSuccess()提示文本换行解决方案

需求 由于接口返回的提示信息过长&#xff0c;接口已经在返回提示中加入换行标签了&#xff0c;但是使用proxy.modal.msgSuccess(res.msg)提示没有换行&#xff0c;那么Vue3中proxy.modal.msgSuccess(res.msg)提示没有换行&#xff0c;那么Vue3 中 proxy.modal.msgSuccess(res.…

[Sync_ai_vid] 唇形同步推理流程 | Whisper架构

链接&#xff1a;https://github.com/bytedance/LatentSync/blob/main/docs/syncnet_arch.md docs&#xff1a;LatentSync LatentSync是一个端到端唇语同步项目&#xff0c;能够生成语音与唇形完美匹配的逼真视频。 该项目通过使用*音频条件化3D U-Net*&#xff08;一种生成式…

uniapp中 ios端 scroll-view 组件内部子元素z-index失效问题

发现子组件中的弹窗在ios手机上会被限制在scroll-view里面&#xff0c;安卓手机上不受限制&#xff0c;网上找了好久原因 scroll-view组件内部设置了 -webkit-overflow-scrolling: touch 样式&#xff0c;导致z-index失效&#xff08;safari 3D变换会忽略z-index的层级问题&…

PyTorch图像预处理完全指南:从基础操作到GPU加速实战

引言 图像预处理是模型性能的"隐形基石"&#xff0c;在计算机视觉任务中直接决定模型能否提取有效特征。科学的预处理流程能让基础模型性能提升15%以上&#xff0c;而GPU加速预处理可使数据准备阶段耗时降低60%以上。本文将聚焦PyTorch预处理核心技术&#xff0c;从基…

【前端教程】 CSS浮动布局解析与优化:从基础实现到工程化改进

浮动(float)是CSS中实现页面布局的经典技术,虽然现代布局更多使用Flexbox和Grid,但理解浮动的工作原理仍是前端开发者的基础素养。本文以一个三栏浮动布局的代码为例,从布局原理解析、潜在问题诊断、工程化优化三个维度,带你深入理解浮动布局的精髓与优化思路。 一、原代…

DVWA靶场通关笔记-暴力破解(Impossible级别)

目录 一、查看源码 二、功能分析 三、SQL注入分析 1、使用PDO预处理语句和参数绑定 2、mysqli_real_escape_string转义 3、stripslashes去除反斜杠 四、暴力破解分析 1、token防止暴力破解机制 2、登录失败随机延迟机制 3、登陆失败报错信息相同 4、登陆失败的账户…

IAR工程如何生成compile_commands.json文件(能生成但是clangd不能生成“.cache文件”)

最近一直在使用vscodeclangd的方式编写代码&#xff0c;感觉使用clangd查找函数调用、函数声明、类型定义等等都比使用vscode自带的c/c插件好用太多了。现在我有一个功能是IAR版本的&#xff0c;那么有没有办法生成clangd使用的compile_commands.json文件呢&#xff1f;答案是&…

QT5.14.2、CMake 扩展openCV

一、准备工具Qt5.14.2c11cmake3.24.0opencv3.4.16二、使用cmake可扩展opencv 首先解压cmake、opencv 两个下载的压缩包&#xff0c;如下&#xff1a;运行cmake-gui.exe打开后有弹窗选择&#xff0c;然后进入QT的安装路径下找 mingw73_64文件下的 C和C的执行文件这个截图是我扩展…

【3D入门-指标篇下】 3D重建评估指标对比-附实现代码

3D重建评估指标对比表 每个指标的具体代码位于文章末尾指标计算方法数值范围评估重点优缺点适用场景Chamfer Distance (C1)从预测网格到真实网格的平均距离[0, ∞)几何形状准确性优点&#xff1a;直观、计算高效缺点&#xff1a;对噪声敏感整体形状评估Chamfer Distance (C2)从…

香港电讯创新解决方案,开启企业数字化转型新篇章

在数字化浪潮席卷全球的今天&#xff0c;企业正加速突破传统办公和业务模式的桎梏&#xff0c;力求通过高效协同与业务创新实现跨越式发展。香港电讯作为科技解决方案提供商&#xff0c;持续推动技术创新应用。近期&#xff0c;香港电讯通过多项创新应用、产品升级及战略合作&a…

数据分析编程第六步:大数据运算

6.1 数据介绍直接打开集算器运行 createEventsAndUsers.splx 文件&#xff0c;就可以得到如下两张表&#xff08;也可以根据代码中的注释&#xff0c;修改起止日期以及每天的数据量&#xff09;&#xff1a;电商数据表 events.csv字段名含义eventID事件编号, 从 1 开始流水号us…

vue2+elementui 表格单元格增加背景色,根据每列数据的大小 颜色依次变浅显示2

注意&#xff1a; 正数前5和负数后5的颜色是固定的&#xff0c;剩下5之后的数据颜色是根据第5个颜色依次变浅的&#xff1b; 封装的js方法&#xff1a; /*** 最终版表格颜色处理器* param {Array} data 完整表格数据* param {String} field 当前字段名* param {Object} row 当前…

【AOSP】Android Dump 开发与调试指南

在 Android 系统开发与调试中&#xff0c;dump 是一个不可或缺的强大工具。它能够提供关于系统服务、应用程序状态以及底层硬件信息的详细快照。对于希望深入了解 Android 系统内部工作原理、排查复杂问题或进行性能优化的开发者来说&#xff0c;掌握 dump 的使用至关重要。一、…

Qt数据结构与编码技巧全解析

文章目录Qt中的数据结构QDebugqDebug函数QT的内置类型一般都会重载 << 运算符QT的几何规则QString 字符串编码变长 VS 定长QString 适合中转数据吗&#xff1f;Qstring 的底层使用写时复制QString的具体使用QString 的构造函数格式化构造数值转化为字符串字符串转成数值增…

Ubuntu操作系统下MySQL、MongoDB、Redis

在开发和运维过程中&#xff0c;经常需要从Windows客户端远程连接到Ubuntu服务器上的数据库。本文将详细介绍如何在Ubuntu操作系统下安装和配置MySQL、MongoDB和Redis&#xff0c;以允许从Windows客户端进行远程连接&#xff0c;并提供详细的远程连接命令和配置说明。一、MySQL…

校园勤工俭学微信小程序的设计与实现:基于数字化服务生态的赋能体系构建

在高等教育普及化与数字化校园建设的双重驱动下&#xff0c;传统校园勤工俭学管理模式正面临深刻变革。当前高校勤工俭学工作普遍存在岗位匹配效率低下、过程管理粗放、数据孤岛严重等痛点——根据教育部全国学生资助管理中心2022年统计数据&#xff0c;全国普通高校共有约450万…

Apisix工作流程

是的,你的理解基本正确:当请求到达APISIX时,它会先根据请求的URI、Host、请求方法、 headers等信息匹配最合适的路由,然后执行路由关联的插件逻辑,最后转发到路由配置的上游服务。下面详细讲解APISIX处理请求的全链路及可能的情况。 一、请求全链路流程 APISIX处理请求的…

InnoDB存储引擎底层拆解:从页、事务到锁,如何撑起MySQL数据库高效运转(上)

目录 Page页** B树查询 如何加快记录的查询&#xff1f; 索引** 聚簇索引(主键) 二级索引(非主键) 联合索引——多列 bufferPool* Free链表 flush链表 Flush链表刷新方式有如下两种&#xff1a; LRU链表 针对LRU链表方案缺点的优化 redoLog* redo简单日志类型 redo复杂日志类型…

【人工智能99问】GPT4的原理是什么?(32/99)

【人工智能99问】GPT4的原理是什么&#xff1f;(32/99) 文章目录GPT-4简介一、结构与原理二、使用场景三、优缺点分析四、训练技巧与关键改进五、示例说明六、总结GPT-4简介 一、结构与原理 1. 架构设计 GPT-4基于Transformer解码器架构&#xff0c;核心改进包括&#xff1a;…

//Q是一个队列,S是一个空栈,实现将队列中的元素逆置的算法。

#include<stdio.h> #include<stdbool.h> #include<stdlib.h> #define Size 6 typedef struct SqNode//队列结点 {int data;struct SqNode* next; }LinkNode; typedef struct SqQueue//队列 {LinkNode* front, * rear; //头指针和尾指针 }LinkQueue; typedef …