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:
xargs
does not handle quoted newlines.zsh
can 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)