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

如何让传入bash函数的参数中的$dir变量在for循环内正确展开

Bash exec_all_dirs函数延迟展开$dir变量的实现方案

问题根因

你当前写法无法生效的核心原因是:直接执行"$@"时,Bash会将传入的整段单引号字符串识别为单一命令名查找执行,不会对字符串内部的$dir做变量展开。你需要让Bash在循环内dir变量赋值完成后,再解析执行传入的命令串。


方案1:轻量改动(使用eval,适合个人bashrc场景)

仅需修改exec_all_dirs的执行逻辑,配合调用时用单引号包裹命令即可实现需求:

function exec_all_dirs() {
  local curdir="$PWD"
  # 目录数组加双引号兼容带空格的路径
  local dirs=(
    ~/dir1
    ~/dir2
    ~/dir3
  )
  for dir in "${dirs[@]}";
  do
    echo "---------- $dir ---------"
    # 用eval解析执行传入的命令串,此时$dir已赋值会正常展开
    eval "$@"
  done
  cd "$curdir"
}

# 调用时保持单引号包裹命令即可,$dir不会提前展开
function all_func() {
  exec_all_dirs 'cd $dir && another_func_defined_in_bashrc'
}
function all_du() {
  exec_all_dirs 'du -sh $dir'
}

注意:调用时必须用单引号包裹命令串,如果用双引号会导致$dir在传参阶段就提前展开,不符合预期。


方案2:无eval安全方案(适合复杂场景,避免命令注入风险)

如果担心eval带来的潜在命令注入风险,可以把执行逻辑封装为独立函数,将当前遍历的目录作为参数传入调用,完全规避变量展开时机问题:

function exec_all_dirs() {
  local curdir="$PWD"
  local dirs=(
    ~/dir1
    ~/dir2
    ~/dir3
  )
  # 取第一个参数为要执行的动作函数
  local action="$1"
  shift
  for dir in "${dirs[@]}";
  do
    echo "---------- $dir ---------"
    # 把当前目录作为第一个参数传给动作函数
    "$action" "$dir" "$@"
  done
  cd "$curdir"
}

# 定义all_func对应的动作函数
function _func_action() {
  local dir="$1"
  cd "$dir" && another_func_defined_in_bashrc
}
function all_func() {
  exec_all_dirs _func_action
}

# 定义all_du对应的动作函数
function _du_action() {
  local dir="$1"
  du -sh "$dir"
}
function all_du() {
  exec_all_dirs _du_action
}

该方案无需关注变量展开时机,兼容性和安全性更高,适合需要处理带特殊字符的路径、或者命令逻辑复杂的场景。


内容的提问来源于stack exchange,提问作者subtleseeker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:54:01