for arg do
arg=$(printf '%s\n' "$arg" | sed "s/'/'\\\''/g")
set -- "$@" "'$arg'"
shift
done
eval "$@"
This adds single quotes around each positional parameter. The loop iterates over each positional parameter, adds the current one to the end of the list, with single quotes added, and then removes the first (now processed) element.
Before adding '$arg' to the end of the list, any single quotes embedded in $arg are replaced with the string '\'' using sed.
As a function called reval:
reval () {
for arg do
arg=$(printf '%s\n' "$arg" | sed "s/'/'\\\''/g")
set -- "$@" "'$arg'"
shift
done
eval "$@"
}
(Arguments will have trailing newlines removed by this.)
In the bash shell, you can replace the command substitution calling printf and sed in the loop with
arg=${arg//\'/\'\\\'\'}
which has the benefit of preserving trailing newlines. Although in the bash shell, you may instead do
reval () {
eval "${@@Q}"
}
... where ${variable@Q} quotes the value $variable so that it's suitable for shell input. With variable being @, this applies to all positional parameters.
This is similar to what you would get with ${(q)@} in the zsh shell:
reval () {
eval "${(q)@}"
}