I have a function that discards the current environment and runs a script as a freshly login:
# 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
}
The problem with this function is that if it receives empty arguments, that argument is discarded. Example:
#! /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
These parameters are lost on line LOST, because if I print the number of arguments before and after the shift, the number of reported arguments are 8 and 6, respectively.
Is there a way of passing them as empty arguments? (just as the function itself can receive them).
PS: I'm fully aware that for this case in particular I could just use Nevermind, using sudo without the function has the same problem.sudo instead of my function and be done with it. But I'm interested in the general case script -> function -> script argument passing when there are empty arguments.
Doing more testing I've found out that is actually a sudo problem:
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
The problem with my function is that sudo is removing the empty variables. Is there a way to tell sudo keep the empty arguments?
Source: https://bugzilla.sudo.ws/show_bug.cgi?id=679
Workaround: Passing empty arguments to sudo -i
In the meantime, for my case, this smelly code will have to do:
# 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_}"
}
It basically iterates through all arguments. For each, expands the argument, double quotes them escaping any double quote inside the argument value and concatenates them in a single string to be run with bash -c. Not suitable for scripts that internally expands arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With