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

文章目錄

  • 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 …