Shell变量赋值等号两侧不可有空格,引用需加$并推荐双引号包裹;函数内用local声明局部变量;条件判断优先用[[(Bash/Zsh内建,更安全),for遍历文件应避免裸通配符;管道中变量赋值仅限子shell。

变量赋值与引用必须区分等号两侧空格
Linux Shell 中 VAR=value 是合法赋值,而 VAR = value 会报错:命令 = 未找到。Shell 把空格当作分隔符,等号两侧不能有空白。
- 正确写法:
name="Alice"、count=42 - 引用变量必须加
$:echo $name,不加就是字面量name - 推荐用双引号包裹引用:
"$name",避免空格或通配符意外展开 - 局部变量在函数内用
local var=value,否则默认全局
条件判断用 [ 还是 [[?优先选 [[
[ 是 POSIX 兼容的外部命令(常为 /bin/[),[[ 是 Bash/Zsh 内建关键字,更安全、功能更强。生产脚本若确定运行在 Bash 环境,应默认用 [[。
-
[[支持正则匹配:[[ $str =~ ^[0-9]+$ ]] -
[[不做单词拆分和路径展开,[[ $path = "/home/*" ]]不会误触发 glob -
[要求中括号与内容间有空格,[ "$a" = "$b" ]缺空格会报错 - 注意:
[[在 dash/sh 下不可用,跨 shell 可移植脚本才退回到[
for 循环遍历文件名时别直接写 for f in *.log
裸写 for f in *.log 在无匹配文件时,f 的值就是字面量 *.log,极易引发后续命令误操作(比如 rm *.log 变成 rm '*.log')。
- 安全做法:先用
shopt -s nullglob(Bash),让无匹配时展开为空 - 更通用做法:用数组显式捕获结果:
files=( *.log ) if (( ${#files[@]} > 0 )); then for f in "${files[@]}"; do echo "processing $f" done fi - 处理含空格路径时,务必用
"${files[@]}"而非${files[@]},否则会按空格切分
管道中的变量赋值在子 shell 生效,父 shell 看不到
像 echo "1 2 3" | while read a b c; do sum=$((a+b+c)); done; echo $sum 最后输出为空——因为 while 在管道右侧运行于子 shell,sum 的赋值不会回传。
-
解决方法一:用重定向代替管道:
while read a b c; do sum=$((a+b+c)); done <<< "1 2 3"
- 解决方法二:用命令组 + 进程替换(Bash):
while read a b c; do sum=$((a+b+c)); done < <(echo "1 2 3")
- 简单场景可用
mapfile或readarray预读全部输入,再处理 - 这不是 bug,是 POSIX 管道设计使然;依赖管道赋值的逻辑,得从结构上重构










