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

Bash中如何以指定用户身份在函数内部调用另一个自定义函数

问题原因

你当前的写法核心问题是函数定义的展开时机和所属shell上下文不匹配:

  • 最外层执行sudo su user1 -c "$(declare -f f1); f1"的时候,只会把f1的定义传到user1的shell环境里,f2的定义根本没有被带进user1的运行上下文
  • 当f1在user1的shell里执行到调用f2的那行时,$(declare -f f2)是在user1的shell中执行的,这个环境里没有f2的定义,所以展开后是空的,切换到servuser执行的时候自然会报找不到f2的错误。

修复方案

方案1:传递所有依赖函数到目标执行上下文

改动最小的适配方案,适合依赖函数少的场景,只需要在每一层传递函数时把该层所有依赖的函数一起传入即可:

f2(){
     echo "test" > test.txt
}
f1(){
        a=1

        if (($a < 0 ))
        then
                        echo "Not running function."
        else
                        echo "Running function."
                        sudo su servuser -c "$(declare -f f2); f2"

        fi
}
# 最外层同时传入f1和它依赖的f2
sudo su user1 -c "$(declare -f f1 f2); f1"

方案2:提前序列化所有函数统一传递

如果嵌套层级多、依赖函数数量多,可以提前把所有需要用到的函数序列化好,避免逐层传参时漏传:

f2(){
     echo "test" > test.txt
}
f1(){
        a=1
        if (($a < 0 ))
        then
                        echo "Not running function."
        else
                        echo "Running function."
                        sudo su servuser -c "$all_funcs; f2"
        fi
}
# 提前把所有用到的函数序列化存为变量
all_funcs="$(declare -f f1 f2)"
sudo su user1 -c "$all_funcs; f1"

方案3:通过export导出函数调用

如果目标用户的默认登录shell是bash,且你的sudo配置没有禁用环境变量传递,可以用更简洁的导出函数方式实现:

f2(){
     echo "test" > test.txt
}
f1(){
        a=1
        export -f f2
        if (($a < 0 ))
        then
                        echo "Not running function."
        else
                        echo "Running function."
                        sudo -u servuser bash -c 'f2'
        fi
}
export -f f1 f2
sudo -u user1 bash -c 'f1'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:00:04