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
相关产品推荐
相关产品推荐

