On Wed, Jul 20, 2022 at 06:32:22PM +0100, Peter Maydell wrote: > > > + # backslash escape any '\' and '"' characters > > > + printf "%s" "$e" | sed -e 's/\([\"]\)/\\\1/g' > > > > You've fixed the bashism, but at the expense of a non-POSIX use of > > sed. POSIX says the input to sed must be a text file (ending in a > > newline; but $e does not), and as a result it always outputs a newline > > (but you don't want a newline before the closing """). GNU sed > > happens to do what you want for input not ending in a newline, but I > > don't remember off-hand whether BSD sed does, and I know that Solaris > > sed does not. > > I just copied the approach we already take in quote_sh: > > quote_sh() { > printf "%s" "$1" | sed "s,','\\\\'',g; s,.*,'&'," > } > > Is that also relying on this non-portable sed use?
Yep. And since no one has complained, BSD sed probably handles it the way we want (input without a trailing line getting substituted and re-output without a trailing newline). If we cared, this one could also be fixed: quote_sh() { printf "'%s'" "$(printf '%s\n' "$1" | sed "s,','\\\\'',g")" } Also note that we are depending on $1 never containing newlines, because this change would alter the existing: $ quote_sh "a c" 'a' 'c' into: $ quote_sh "a c" 'a c' which is probably more what you wanted. > > > If this passes on BSD, then I'm okay with it; but if we want to avoid > > non-POSIX altogether, this should work (using the shell's $() to strip > > the trailing newline we added to keep sed happy): > > > > # backslash escape any '\' and '"' characters > > printf '"""%s""",' "$(printf "%s\n" "$e" | sed -e '/s/\([\"]\)/\\\1/g')" > > Mmm. Given that no one has complained about quote_sh, insisting on POSIX compliance (with its resulting increase in line noise and length) is not winning any maintainability arguments ;) -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3266 Virtualization: qemu.org | libvirt.org