Hipster1206
Hipster1206

Reputation: 421

Parsing single string argument that has space in bash

What is the best way to parse single string argument(that has space in between) to a bash script ?

#!/bin/bash

eval $@
echo $OPT1
echo $OPT2
echo $OPT3
echo $OPT4

eval works fine when the options are of one word like below

./args.sh 'OPT1=1 OPT2=2 OPT3=3 OPT4=4'
 1 2 3 4

But not when my arguments are like below

./args.sh 'OPT1=1 OPT2=2 OPT3=3.1 3.2 OPT4=4'

What is the better way of parsing the above agruments?

Please note that I have no control over the input arguments, I am using third party binary which just generate these arguments as a single string.

Is there any command similar to eval that will do the parsing based on some delimiter in my case'='

Upvotes: 1

Views: 148

Answers (1)

John1024
John1024

Reputation: 113814

eval is always dangerous. There is, fortunately, a much safer and more reliable way to define variables and that is to use declare.

Try this script:

$ cat args.sh
#!/bin/bash
old=$IFS
IFS=$'\n'
declare "$(sed -E 's/ +([[:alnum:]]+=)/\n\1/g' <<<"$*")"
IFS=$old

#Verify that declare was succesful:
declare -p OPT1 OPT2 OPT3 OPT4

We can run the script to verify that it works as desired:

$ ./args.sh 'OPT1=1 OPT2=2 OPT3=3.1 3.2 OPT4=4'
declare -- OPT1="1"
declare -- OPT2="2"
declare -- OPT3="3.1 3.2"
declare -- OPT4="4"

How it works

  • #!/bin/bash

    This shebang line specifies bash as the shell

  • old=$IFS

    This saves the old value of IFS.

  • IFS=$'\n'

    This sets IFS to be just a newline character.

  • declare "$(sed -E 's/ +([[:alnum:]]+=)/\n\1/g' <<<"$*")"

    The sed command reformats the input to put each declaration on a separate line. The output is suitable as arguments to declare.

  • IFS=$old

    This restores the old value of IFS.

  • declare -p OPT1 OPT2 OPT3 OPT4

    This is a diagnostic statement so that we can verify the variables have been defined as we want.

Upvotes: 3

Related Questions