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

如何通过`sudo -s`传递含美元符号的变量至Shell子脚本?

解决包含美元符号的参数在sudo -s调用子脚本时被解析的问题

这个问题的核心是sudo -s会启动一个新的shell进程,它会对传递的参数进行二次解析,导致原字符串中的$被当作变量展开,最终丢失了原有的内容。下面是两种可行的解决方法:

方法一:移除不必要的sudo -s

如果你的场景不需要启动登录shell(-s参数的作用),直接用sudo执行子脚本即可,这样参数会直接传递,不会被额外解析:

修改test.sh为:

#! /bin/sh
echo "test arguments: $@"
variable=$1
sudo -u $USER ./subtest.sh "$variable"

这种方法最简单,也是最推荐的,因为-s通常用于需要加载用户环境变量的场景,如果只是执行一个脚本,完全不需要它。

方法二:对参数进行shell转义(必须用sudo -s时)

如果因为某些原因必须保留sudo -s,我们需要把参数转义成shell无法解析的格式,确保原字符串完整传递。可以用printf "%q"来实现自动转义:

修改test.sh为:

#! /bin/sh
echo "test arguments: $@"
variable=$1
sudo -u $USER -s ./subtest.sh "$(printf "%q" "$variable")"

printf "%q"会把输入的字符串转义成适合shell作为参数的格式,比如abc$def会被转义成abc\$def,这样新启动的shell就不会把$def当作变量展开,而是保留原有的$符号。

为什么原来的写法会失效?

当你用sudo -s ./subtest.sh "$variable"时,sudo会启动一个新的shell,然后把./subtest.sh "$variable"作为命令传递给这个新shell。此时新shell会重新解析这个命令字符串:如果variable的值是abc$def,新shell会尝试展开$def(而这个变量在新shell中不存在,会被替换为空),最终传递给subtest.sh的参数就变成了abc,而非原字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:22:40