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

Bash中runuser存入变量执行带参数脚本失败的解决问询

问题:Bash中runuser执行带参数脚本时的引号解析错误

需求:编写Bash脚本,判断当前用户是root还是非root,以对应身份执行带参数的目标脚本并检查执行结果。但使用runuser时,将命令存入变量后执行,Bash无法正确识别引号,导致runuser误将目标脚本的参数-s当作自身参数,报错:

runuser: option requires an argument -- 's'

原问题代码

#!/bin/bash
check_other_script(){
        user=mruser
        bin_dir=/home/$user/bin
        script_name=myscript
        decho "[d] Performing $script processing of settings check"
        sub_cmd="${bin_dir}/${script_name} -s"
        if [ "$running_user_type" == "root" ]; then
                        #cmd="runuser -l $user -c "$sub_cmd""
        elif [ "$running_user_type" == "non-root" ]; then
                        cmd="$sub_cmd"
        fi
        decho "[d] command to run: $cmd"
        $cmd
    status="$?"
    decho "[d] script status code: $status."

}

check_other_script
exit 0

错误原因

将完整命令存入普通字符串变量后,Bash执行$cmd时会进行单词拆分,完全忽略字符串内的引号边界。比如你尝试的各种引号写法,最终展开后runuser会把/home/mruser/bin/myscript当作-c的唯一参数,而-s会被当成runuser自身的命令行参数,触发参数解析错误。

正确实现方式

方法1:使用数组存储命令(推荐)

Bash数组可以精准保留每个参数的边界,避免单词拆分问题:

#!/bin/bash
check_other_script(){
        user=mruser
        bin_dir=/home/$user/bin
        script_name=myscript
        decho "[d] Performing $script processing of settings check"
        sub_cmd="${bin_dir}/${script_name} -s"
        if [ "$running_user_type" == "root" ]; then
                        # 数组每个元素对应一个命令参数
                        cmd=(runuser -l "$user" -c "$sub_cmd")
        elif [ "$running_user_type" == "non-root" ]; then
                        cmd=("$sub_cmd")
        fi
        decho "[d] command to run: ${cmd[*]}"
        # 用数组展开方式执行,保留参数边界
        "${cmd[@]}"
        status="$?"
        decho "[d] script status code: $status."

}

check_other_script
exit 0

方法2:直接执行,不存入变量

如果逻辑简单,可直接在分支内执行命令,规避变量存储带来的解析问题:

#!/bin/bash
check_other_script(){
        user=mruser
        bin_dir=/home/$user/bin
        script_name=myscript
        decho "[d] Performing $script processing of settings check"
        sub_cmd="${bin_dir}/${script_name} -s"
        if [ "$running_user_type" == "root" ]; then
                        runuser -l "$user" -c "$sub_cmd"
        elif [ "$running_user_type" == "non-root" ]; then
                        "$sub_cmd"
        fi
        status="$?"
        decho "[d] script status code: $status."

}

check_other_script
exit 0

方法3:使用eval(不推荐)

eval可强制重新解析引号,但存在安全风险(若变量包含恶意内容会被执行),仅在可控场景下使用:

#!/bin/bash
check_other_script(){
        user=mruser
        bin_dir=/home/$user/bin
        script_name=myscript
        decho "[d] Performing $script processing of settings check"
        sub_cmd="${bin_dir}/${script_name} -s"
        if [ "$running_user_type" == "root" ]; then
                        cmd="runuser -l $user -c \"$sub_cmd\""
        elif [ "$running_user_type" == "non-root" ]; then
                        cmd="$sub_cmd"
        fi
        decho "[d] command to run: $cmd"
        eval "$cmd"
        status="$?"
        decho "[d] script status code: $status."

}

check_other_script
exit 0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:12:02