shell/shell-括号.md
2025-03-28 20:10:14 +08:00

8.0 KiB
Raw Permalink Blame History

Shell 括号


一:括号介绍

1. 圆括号

特性 (())
用途 子 Shell 执行、命令替换、数组定义 整数算术运算、循环条件
执行环境 在子 Shell 中运行,不共享当前变量 在当前 Shell 中执行算术操作
变量影响 子 Shell 内变量修改不影响父 Shell 直接修改当前 Shell 的变量
示例 (a=1; echo $a)(退出后 a 恢复原值) ((a=5+3))(直接赋值给 a
逻辑运算 不适用 支持 &&, `
返回值 返回子 Shell 中最后一条命令的退出码 返回算术表达式是否为真0为真非0为假

2. 方括号

特性 [ ]test 命令) [[ ]]Bash 增强条件)
兼容性 POSIX 标准,所有 Shell 支持 Bash/Ksh/Zsh 特有,非 POSIX
字符串比较 =!=,需严格转义空格 直接支持 ==!=,无需转义
模式匹配 不支持通配符(需用 case 支持通配符(如 [[ $file == *.txt ]]
正则匹配 不支持 支持 =~(如 [[ "abc" =~ ^a ]]
逻辑运算符 必须用 -aAND-oOR 直接使用 &&、`
变量处理 变量未加引号可能导致语法错误 自动处理变量中的空格和特殊字符
数值比较 -eq-lt 也可用 -eq,但推荐 (( ))
示例 [ "$a" -eq 5 -a "$b" != "" ] [[ $str == "yes" && $num > 10 ]]

3. 花括号

特性 用途 示例
代码块 组合命令(当前 Shell 执行) { cmd1; cmd2; } > log.txt
序列生成 生成数字/字母序列 echo {1..5}1 2 3 4 5
文件名扩展 快速枚举文件或路径 cp file.{txt,bak}cp file.txt file.bak
变量操作 字符串处理、默认值替换等 ${var:-default}(空值时替换)
注意 代码块首尾必须有空格和分号 { echo "Start"; ls; }

4. 总对比

括号类型 核心用途 关键区别 示例
() 子 Shell、数组、命令替换 子 Shell 中运行,不共享变量 (cd /tmp; ls)
(( )) 整数算术运算、循环条件 直接操作变量,支持 C 风格语法 for ((i=0; i<10; i++))
[ ] 基础条件测试(兼容 POSIX 严格空格,需转义符号 [ -f file ]
[[ ]] 增强条件测试Bash 特有) 支持通配符、正则、逻辑运算符 [[ $str =~ ^[0-9]+$ ]]
{} 代码块、序列生成、变量扩展 不创建子 Shell直接扩展内容 echo {A..C}A B C

5. 常见误区

  1. 空格要求:
    • [ ][[ ]] 内部必须保留空格:[ "$a" = 5 ] ✔️[$a=5]
    • (( ))[[ ]] 中的变量无需 $ 符号:((a++)) ✔️(($a++))
  2. 字符串比较:
    • [ ] 中必须用引号包裹变量,避免空值错误:[ "$str" = "hello" ]
    • [[ ]] 中可不加引号(自动处理):[[ $str == hello ]]
  3. 数值比较:
    • [ ] 必须用 -eq-lt 等操作符:[ $a -gt 10 ]
    • [[ ]](( )) 中可直接用 ><[[ $a > 10 ]]((a > 10))
  4. 逻辑运算符:
    • [ ] 中用 -aAND-oOR[ $a -eq 1 -o $b -eq 2 ]
    • [[ ]] 中用 &&||[[ $a == 1 && $b == 2 ]]

二:示例

1. 圆括号

用途

  • 子 Shell 执行:在独立环境中运行命令,不影响当前 Shell。
  • 令替换:捕获命令输出。
  • 数组定义:初始化数组。

示例:

# 子 Shell 示例:临时切换目录,不影响当前 Shell
[root@wxin ~]# (current_dir=$(pwd); cd /tmp; ls; cd "$current_dir")

# 命令替换:获取当前日期
[root@wxin ~]# today=$(date +"%Y-%m-%d")
[root@wxin ~]# echo "今天是$today"
今天是2025-03-26

# 数组定义
[root@wxin ~]# fruits=("apple" "banana" "cherry")
[root@wxin ~]# echo "第二个水果是 ${fruits[1]}"
第二个水果是 banana

2. 双括号

用途

  • 整数算术运算:替代 expr,支持 C 语言风格语法。
  • 循环条件:简化 for/while 循环。

示例:

# 算术运算
[root@wxin ~]# (( sum = 3+5*2 ))
[root@wxin ~]# echo "结果是 $sum"
结果是 13

# 自增操作
[root@wxin ~]# count=0
[root@wxin ~]# (( count++ ))
[root@wxin ~]# echo "计数: $count"
计数: 1

# 循环条件
[root@wxin ~]# for (( i=0;i<3;i++ ));do
> echo "循环第 $i 次"
> done
循环第 0 次
循环第 1 次
循环第 2

3. 方括号

用途

  • 条件测试:兼容 POSIX 的基础条件判断。
  • 文件检查:测试文件属性(如是否存在、是否可读)。

示例:

# 数值比较
[root@wxin ~]# if [ "$a" -eq 10 ];then echo "a 等于 10"; fi
a 等于 10

# 文件存在性检查
[root@wxin ~]# if [ -f "/etc/passwd" ];then
> echo "文件存在"
> fi
文件存在

# 逻辑组合(使用 -a/-o
[root@wxin ~]# if [ "$a" -gt 5 -a "$a" -lt 15 ];then
> echo "a 在 5 到 15 之间"
> fi
a 在 515 之间

4. 双括号

用途

  • 增强条件测试:支持通配符、正则表达式和逻辑运算符。
  • 模式匹配:直接使用 ===~

示例:

# 字符串匹配(支持通配符)
[root@wxin ~]# file="image.jpg"
[root@wxin ~]# if [[ "$file" == *.jpg ]];then
> echo "这是一个 JPEG 文件"
> fi
这是一个 JPEG 文件

# 正则表达式匹配
[root@wxin ~]# phone="123-456-7890"
[root@wxin ~]# if [[ "$phone" =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]];then
> echo "有效的电话号码"
> fi
有效的电话号码

# 逻辑运算符(直接使用 &&/||
[root@wxin ~]# str="hello"
[root@wxin ~]# num=8
[root@wxin ~]# if [[ "$str" == "hello" && $num -gt 5 ]];then
> echo "条件满足"
> fi
条件满足

5. 花括号

用途

  • 代码块:组合命令(当前 Shell 执行)。
  • 序列生成:快速生成数字或字母序列。
  • 文件名扩展:批量操作文件。
  • 变量操作:字符串处理和默认值替换。

示例:

# 代码块(重定向所有输出)
[root@wxin ~]# {
> echo "操作开始于 $(date)"
> ls -l
> echo "操作结束"
> } > log.txt

# 序列生成
[root@wxin ~]# echo {1..5}
1 2 3 4 5
[root@wxin ~]# echo {A..C}
A B C
[root@wxin ~]# echo file{1..3}.txt
file1.txt file2.txt file3.txt

# 文件名扩展(快速复制备份)
[root@wxin ~]# cp config.txt{,.bak}

# 变量默认值替换
[root@wxin ~]# unset var
[root@wxin ~]# echo "${var:-默认值}"
默认值

# 字符串截取
[root@wxin ~]# filename="photo.jpg"
[root@wxin ~]# echo "${filename%.*}"
photo
[root@wxin ~]# echo "${filename##*.}"
jpg