yolenoyer
yolenoyer

Reputation: 9445

Convert bash array to a single stringified shell argument list, handable by "sh -c"

This question looks similar to many questions on SO, but I didn't find a real answer.

Sometimes I need to run sh -c "$my_command", where $my_command has to be created from a bash array of arguments (whatever the arguments look like).

Here is my solution, but I wonder if there is a better, (maybe native) bash solution for this?

#!/bin/bash

# My solution:
args_to_shell_escaped_string() {
    local arg
    for arg in "$@"; do
        printf '%q ' "$arg"
    done
}

# Testing it:
args=(
    'arg with spaces'
    'arg with; !! any { special $char'
)

escaped_args=$(args_to_shell_escaped_string "${args[@]}")

sh -c "
for a in $escaped_args; do
    echo \">> \$a\"
done
"

Upvotes: 1

Views: 65

Answers (2)

tjm3772
tjm3772

Reputation: 3154

The standard solution is to just pass your arguments as positional arguments to the program.

sh -c 'for a ; do echo ">> $a" ; done' _ "${args[@]}"

I'd personally argue that it's bad practice to embed variables directly into a sh -c command even if you're trying to take special care to escape them. One missed escape is all it takes to introduce bugs or security flaws.

Upvotes: 0

oguz ismail
oguz ismail

Reputation: 50795

Yes, there is the Q parameter transformation.

sh -c "
for a in ${args[*]@Q}; do
    echo \">> \$a\"
done
"

Upvotes: 2

Related Questions