2011-11-6, 21:02(-06), Peng Yu: [...] > #!/usr/bin/env bash > > verbatim_string=" a b c ( a'b | " > > args="`echo \"$verbatim_string\" | sed -f quoteverb.sed`" > > cmd="echo $args" > eval "$cmd" > > ~$ ./main.sh > a b c ( a'b |
Either: #! /bin/sh verbatim_string=" a b c ( a'b | " cmd='(set -f; IFS=" "; echo $verbatim_string)' eval "$cmd" ($verbatim_string expanded and split at the time $cmd is evaluated). Or: #! /bin/bash verbatim_string=" a b c ( a'b | " set -f; IFS=' ' cmd="echo $(printf '%q ' $verbatim_string)" eval "$cmd" ($verbatim_string expanded and split and quoted initially). (echo being a poor choice of a command for testing as it concatenates its arguments and possibly handles "\" characters specially under some circumstances). By the way, does bash have any way of introducing local scope for options, similar to zsh's (){ setopt localoptions noglob shwordsplit local IFS=' ' args=($string) } Or to set the options to defaults in a local scope to be able to write code that works whatever the context, like zsh's: f() { emulate -L zsh # ensure default zsh behavior even if caller # has changed some settings ... } I suppose one can add default_settings=$(set +o) at the start of the script, and then f() { local restore_settings restore_settings=$(set +o) eval "$default_settings" ... eval "$restore_settings" } Or is there any more canonical way to do it? -- Stephane