sudo -i调用Bash函数报unexpected end of file错误的原因是什么
问题原因分析
这个错误是sudo -i的参数解析逻辑和其他调用方式不一致导致的,核心点如下:
sudo -i的本质是启动目标用户的登录shell,它会先加载目标用户的所有登录态配置(.bash_profile、.profile等),再执行后续传入的命令,和普通sudo直接执行命令的逻辑完全不同。- 你写的
"$(declare -f hello); hello"在当前shell先完成展开,得到的内容是带换行、双引号的函数定义+调用语句,类似下面的结构:
hello () { echo "Hello! user=$USER, uid=$UID, home=$HOME" }; hello
- 前两种调用方式是直接把上面展开后的完整字符串作为
bash -c的参数传入,语法完整所以运行正常。但sudo -i会把所有传入的参数先做一次拼接和命令行解析,这个过程会把你展开内容里的换行、引号结构直接拆碎,最终传给bash -c的内容是不完整的,所以抛出unexpected end of file语法错误。
修复方案
如果必须使用-i(登录shell)模式执行,你可以通过下面两种方式避免转义问题:
- 把函数定义转成单行格式,消除换行的影响:
sudo -i -u $USER bash -c "$(declare -f hello | tr '\n' ' '); hello"
- 用base64编码绕过特殊字符解析问题,兼容性最好:
# 把要执行的内容编码后传入,目标shell解码执行 run_cmd="$(declare -f hello); hello" sudo -i -u $USER bash -c "base64 -d <<< '$(base64 -w0 <<< "$run_cmd")' | bash"
内容的提问来源于stack exchange,提问作者user14825657
相关产品推荐
相关产品推荐

