The command printf %q (from GNU coreutils or bash) can be used to quote an array of arguments including whitespaces, newlines and quotes. For example:
$ main() { printf '%q ' "${@}"; } && main "'a'" '"b"' 'c d' $'e\nf'
\'a\' \"b\" c\ d $'e\nf'
Is it possible to reverse this operation, i.e. create an argument array from a string created by printf %q
- In a POSIX shell?
- In Bash?
- Using additional tools?
Insights:
xargsdoes not handle quoted newlines.zshcan do this for a string stored in variableargs:"${(Q@)${(z)args}}"
CodePudding user response:
main() { printf '%q ' "${@}"; }
str=$(main "'a'" '"b"' 'c d' $'e\nf')
It's really simple. Use the following to re-set positional arguments:
eval "set $str"
CodePudding user response:
use declare:
quoted=$(main "'a'" '"b"' 'c d' $'e\nf')
declare -a "myvar=($quoted)"
declare -p myvar
outputs
declare -a myvar=([0]="'a'" [1]="\"b\"" [2]="c d" [3]=$'e\nf')
This can't be used to evaluate commands:
$ declare -a "myvar=($(main ls -l sensitive files))"
$ declare -p myvar
declare -a myvar=([0]="ls" [1]="-l" [2]="sensitive" [3]="files")
One thing to note: if you use declare in a function, the variable becomes local to that function (unless you use declare -g in which case it's global)
