You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

bash中如何正确使用包含星号*的路径变量?

解决方案

前提说明

星号通配符展开分为两个阶段:

  • 命令行传参阶段:如果用户执行脚本时没有用单引号包裹带*的参数(例如直接写./your_script.sh /home/*),*会在脚本启动前就被shell展开为具体路径,脚本无法获取原始带星号的参数。因此要求用户传带通配符的参数时必须用单引号包裹:./your_script.sh '/home/*'
  • 脚本内部解析阶段:未加引号的变量调用会触发shell二次展开,这是现有代码的核心问题。

代码修正方案

1. 参数接收部分修正

原有代码有两个错误:未给$@加引号导致展开、数组追加语法错误,不需要循环,直接一行就能正确接收所有参数且保留原始字符:

#!/bin/bash
# 直接接收所有参数存入数组,双引号保证参数原样保留不展开
dir=("$@")

如果一定要用循环实现,写法如下:

dir=()
for i in "$@"; do
  dir+=("$i")
done

2. 逻辑判断部分修正

原有${dir[*]}未加引号会触发展开,遍历数组必须用"${dir[@]}"才能保留每个元素的原始值:

for i in "${dir[@]}"; do
  # 判断参数包含星号的逻辑保持不变
  if [[ "$i" == *"*"* ]]; then
    # 给$i加引号避免shell提前展开星号,交给find处理通配符匹配
    find "$i" -maxdepth 1 -type d
  fi
done

备选方案:临时关闭通配符展开

如果需要避免脚本内部任何位置的通配符展开,可以在脚本开头开启noglob选项,关闭路径通配符解析功能:

#!/bin/bash
# 关闭通配符展开
set -o noglob

# 后续所有变量调用都不会触发*展开,代码可以不用额外加引号处理
dir=("$@")
for i in "${dir[@]}"; do
  if [[ "$i" == *"*"* ]]; then
    find $i -maxdepth 1 -type d
  fi
done

# 可选:处理完成后恢复通配符展开
set +o noglob

注意:该方案只能避免脚本内部的展开,依然要求用户传参时用单引号包裹带*的参数。

内容的提问来源于stack exchange,提问作者Jörg Kauke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:00:00