0

I want to quote the arguments in dash (or sh, or even bash if that's not possible). I can do that with "${(q+@)@}" in zsh, such that reval <sth> ... is the same as just typing in <sth> ... in the terminal:

reval () {
    eval "$(gquote "$@")"
}
gquote () {
    print -r -- "${(q+@)@}"
}
HappyFace
  • 1,612
  • 2
    This answer may be useful? possibly skimming through it until "the conclusion" – LL3 Jul 28 '20 at 12:05
  • not sure if that may related to your problem https://stackoverflow.com/a/48720056 or https://stackoverflow.com/a/62375262 or https://stackoverflow.com/a/62922701 maybe a combination of that answers will help you for (da)sh compatible solution – alecxs Jul 29 '20 at 03:27

1 Answers1

0
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 &quot;$@&quot;

}

(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)@}"
}
Kusalananda
  • 333,661