LinuxShell常用语法说明_高频写法解析【指导】

21次阅读

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

LinuxShell常用语法说明_高频写法解析【指导】

变量赋值与引用必须区分等号两侧空格

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")
  • 简单场景可用 mapfilereadarray 预读全部输入,再处理
  • 这不是 bug,是 POSIX 管道设计使然;依赖管道赋值的逻辑,得从结构上重构

真正难的不是记住语法,是理解哪些看似“能跑”的写法,在边界条件下会静默失败。比如空目录下的通配符、含换行符的变量、子 shell 作用域——这些地方不加验证,上线后才暴露,比语法错误更难 debug。

text=ZqhQzanResources