shell - Bash: Reading quoted/escaped arguments correctly from a string -


i'm encountering issue passing argument command in bash script.

poc.sh:

#!/bin/bash  args='"hi there" test' ./swap ${args} 

swap:

#!/bin/sh echo "${2}" "${1}" 

the current output is:

there" "hi 

changing poc.sh (as believe swap want correctly), how poc.sh pass "hi there" , test 2 arguments, "hi there" having no quotes around it?

a few introductory words

if @ possible, don't use shell-quoted strings input format.

  • it's hard parse consistently: different shells have different extensions, , different non-shell implementations implement different subsets (see deltas between shlex , xargs below).
  • it's hard programatically generate. ksh , bash have printf '%q', generate shell-quoted string contents of arbitrary variable, no equilavent exists in posix sh standard.
  • it's easy parse badly. many folks consuming format use eval, has substantial security concerns.

nul-delimited streams far better practice, can accurately represent any possible shell array or argument list no ambiguity whatsoever.


xargs, bashisms

if you're getting argument list human-generated input source using shell quoting, might consider using xargs parse it. consider:

array=( ) while ifs= read -r -d '';   array+=( "$reply" ) done < <(xargs printf '%s\0' <<<"$args")  swap "${array[@]}" 

...will put parsed content of $args array array. if wanted read file instead, substitute <filename <<<"$args".


xargs, posix-compliant

if you're trying write code compliant posix sh, gets trickier. (i'm going assume file input here reduced complexity):

# not work entries containing literal newlines; need bash that. run_with_args() {   while ifs= read -r entry;     set -- "$@" "$entry"   done   "$@" } xargs printf '%s\n' <argfile | run_with_args ./swap 

these approaches safer running xargs ./swap <argfile inasmuch throw error if there more or longer arguments can accommodated, rather running excess arguments separate commands.


python shlex -- rather xargs -- bashisms

if need more accurate posix sh parsing xargs implements, consider using python shlex module instead:

shlex_split() {   python -c ' import shlex, sys item in shlex.split(sys.stdin.read()):     sys.stdout.write(item + "\0") ' } while ifs= read -r -d '';   array+=( "$reply" ) done < <(shlex_split <<<"$args") 

Comments

Popular posts from this blog

qt - Using float or double for own QML classes -

Create Outlook appointment via C# .Net -

ios - Swift Array Resetting Itself -