Reputation: 421
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
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"
#!/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