Bash:将带有空变量的 "$@"参数传递给 sudo -i

标签 bash function operators

我有一个函数可以丢弃当前环境并运行脚本作为新登录:

# Recieves a username, a script path and the arguments of the script
run_in_new_login() {
    local user
    local script

    user=$1
    script=$2

    shift 2

    sudo -i -u "${user}" -H bash "${script}" "$@"  # LOST
}

这个函数的问题在于,如果它接收到空参数,该参数将被丢弃。示例:

#! /usr/bin/env bash
# ~/print_n_args.sh

echo "Recieved $# arguments"
param3=hello
param4="last_one_detected"
param5=""
param6=""

run_in_new_login ${USER} print_n_args.sh param1 param2 "${param3}" "${param4}" "${param5}" "${param6}"
> Recieved 4 arguments

这些参数在 LOST 行丢失了,因为如果我打印移位前后的参数数量,报告的参数数量分别为 8 和 6。

有没有办法将它们作为空参数传递? (就像函数本身可以接收它们一样)。


PS:我完全知道,对于这种情况,我可以只使用 sudo 而不是我的函数,然后就可以完成它了。但我对一般情况脚本 -> 函数 -> 脚本参数在参数为空时传递感兴趣。 没关系,在没有函数的情况下使用 sudo 也有同样的问题。


编辑

做更多的测试我发现这实际上是一个 sudo 问题:

sudo -u ${USER} -i -H bash print_n_args.sh param1 param2 "${param3}" "${param4}" "${param5}" "${param6}"
> Recieved 4 parameters

bash print_n_args.sh param1 param2 "${param3}" "${param4}" "${param5}" "${param6}"
> Recieved 6 parameters

我的函数的问题是 sudo 正在删除空变量。有没有办法告诉 sudo 保留空参数?

最佳答案

这是一个错误

来源:https://bugzilla.sudo.ws/show_bug.cgi?id=679

解决方法:Passing empty arguments to sudo -i


与此同时,对于我的情况,这段难闻的代码必须做:

# Recieves a username, a filepath and the arguments to the script
run_in_new_login() {
    if [ "$#" -lt "2" ]; then
        log_error "Not enough arguments to run_in_new_login"
        return 1
    fi

    local user
    local script
    local command_
    local escaped

    user=$1
    script=$2

    shift 2

    command_="${script}"

    for val in "$@"; do
        escaped="$(sed 's/"/\\"/g' <<<"${val}")"
        command_="${command_} \"${escaped}\""
    done

    sudo -i -u "${user}" -H bash -c "${SHELL} ${command_}"
}

它基本上遍历所有参数。对于每个,扩展参数,将它们加双引号以转义参数值内的任何双引号,并将它们连接成单个字符串以使用 bash -c 运行。 不适合内部扩展参数的脚本。

关于Bash:将带有空变量的 "$@"参数传递给 sudo -i,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58961958/

相关文章:

linux - 如何使用 bash 脚本显示 "setup" screen

arrays - 数组公式在 Excel 中不起作用

PHP - 不是运算符,还有其他别名吗?

c++ - 有没有办法让重载运算符的两个拷贝返回不同的类型?

bash - Gradle 无法识别我设置的 JAVA_HOME

bash - 查看多个git仓库的日志

bash - 如何有效地将多个大 .gz 文件合并为一个?

php codeigniter事件记录替换功能

python - 列出python命名空间中的所有元素

C++ - 我应该使 `operator+` 为常量吗?它会返回引用吗?