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

Posted

技术标签:

【中文标题】Bash:将带有空变量的“$@”参数传递给 sudo -i【英文标题】:Bash: pass "$@" argument with empty variables to sudo -i 【发布时间】:2020-03-16 14:53:14 【问题描述】:

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

# 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 保留空参数?

【问题讨论】:

我不确定确切的原因,但它与您使用-i 有关(这会导致sudo 使用其-c 选项运行您的登录shell)。 sudo -u $USER -H bash ... 按预期工作。 一些额外的测试表明这确实是一个错误,因为包含空格的参数被保留而不是拆分;只有空参数消失。 嗯,所以这不应该发生? 好的,我在bugtracker 和关联的*** question 中发现了这个错误 【参考方案1】:

这是一个错误

来源: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的主要内容,如果未能解决你的问题,请参考以下文章

RMarkdown:如何将参数传递给在 R 中定义为变量的 bash 块?

如果我声明一个带有空参数表的函数,然后将参数传递给它怎么办?

如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? [复制]

执行 curl 获取的脚本时将参数传递给 bash

如何将数组参数传递给 Bash 脚本

将参数传递给 callableSatament - ORA-01008: 并非所有变量都绑定