printf
is both a command in msys and a builtin in bash. Only the bash builtin supports %q
. This means that invoking it from Tcl is rather more tricky than normal, as you've got to negotiate bash's quoting as well. This requires this rather awkward construction:
exec bash -c {printf %q "$0"} $s
The part inside the braces is shell syntax, but the rest is Tcl syntax; by doing it like this, it will work with (and so correctly shell-quote) any input. Note that Tcl's braces work just like bourne shell single quotes, except they're nestable.
If you then want to use the special form in bash, you then substitute it into the bash script in Tcl:
set quoted [exec bash -c {printf %q "$0"} $s]
exec bash -c "eval $quoted"
(This is OK. The printf %q
does exactly the quoting to make this work; that's its purpose.)
If you've got a complicated script that will be using the quoted fragment where you don't want to do this, you end up with passing it in as an argument again and using another eval
where necessary:
exec bash -c {
# You can get *really* complicated in here!
eval eval "$0"
} $quoted
But if this is going on, it might be time to consider whether your approach is the right one…