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

Shell脚本切换用户后变量未解析,如何传递变量值?

问题根源分析

你遇到的问题本质是Shell引号的变量解析规则在切换用户时搞的鬼:当你用su test2 -c '命令'这种形式时,单引号会强制Shell把内部所有内容原样传递给test2的Shell环境执行——但test2的环境里根本没有$user这个变量,所以它被解析成了空值,最终执行的命令变成了touch /home/test2/.file,自然就生成了错误的.file文件。

解决方案

根据不同场景,有几种可靠的解决方式:

方式1:改用双引号包裹执行命令

双引号会让当前Shell(test1的Shell)先解析$user变量,再把解析后的完整命令传递给test2执行:

#!/bin/bash
user="test1"
# 用双引号包裹要执行的命令,让当前Shell先解析变量
su test2 -c "touch /home/test2/$user.file"

这样当前Shell会先把$user替换成test1,传给test2的命令就是touch /home/test2/test1.file,执行后就能生成正确的文件。

方式2:单引号+变量拼接(适合命令内有其他单引号的场景)

如果你的命令里必须用到单引号(比如涉及字符串匹配、转义等),可以把$user部分单独用双引号包裹,和单引号内容拼接起来:

#!/bin/bash
user="test1"
# 单引号部分原样传递,变量部分由当前Shell解析后拼接
su test2 -c 'touch /home/test2/'"$user"'.file'

这里'touch /home/test2/'是原样传递的字符串,"$user"被当前Shell解析为test1,'.file'也是原样传递,最终组合成正确的命令。

方式3:用sudo替代su(更简洁的写法)

如果你的环境允许使用sudo,这种写法会更直观,同样注意用双引号让当前Shell解析变量:

#!/bin/bash
user="test1"
# 指定以test2用户身份执行touch命令
sudo -u test2 touch "/home/test2/$user.file"

-u test2指定执行用户,双引号确保$user被正确解析后再传递给touch命令。

额外提示

如果需要传递多个变量或者更复杂的命令给目标用户,也可以考虑先把变量导出为环境变量,再让目标用户继承:

#!/bin/bash
user="test1"
export user
su test2 -c 'touch /home/test2/$user.file'

不过这种方式需要目标用户的Shell允许继承环境变量(默认大部分是允许的),但相比前面的引号方式可读性稍差,一般推荐前两种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:37:15