0

I am trying to redirect the output of a command that contains couple of user input variables to an array. I first tried this script -

echo "Type the ACL name"
read acl
echo "Type the DATACENTER name"
read dc
echo "ACL is $acl, DC is $dc"
mkdir ~/$acl
device=($(grep -iEr $acl ~/sync-configs/$dc/configs/* | awk -F ':' {'print $1'} | awk -F '/' {'print $NF'} | sort | uniq))

The script created the ~/acl directory just fine but the grep did not work for me. Then, after doing some research, I adjusted the grep to put the variables in double quotes, like this -

echo "Type the ACL name"
read acl
echo "Type the DATACENTER name"
read dc
echo "ACL is $acl, DC is $dc"
mkdir ~/$acl
device=($(grep -iEr "$acl" ~/sync-configs/"$dc"/configs/* | awk -F ':' {'print $1'} | awk -F '/' {'print $NF'} | sort | uniq))

This seems to work fine and I am able to see elements in the device array.

My question is why do I need to put the $acl and $dc quotes when feeding them to the array but the command mkdir ~/$acl doesn't require any quotes? Can some one provide clarity on this?

  • That would depend on what you enter for acl and dc, wouldn't it. – Satō Katsura May 13 '17 at 5:35
  • Ah...my acl input is a string. So..that is why i need to escape it with quotes in the grep command? But then, why dont I need to escape it in the mkdir ~/acl command? – user168115 May 13 '17 at 5:40
  • That isn't remotely what I said. shrug – Satō Katsura May 13 '17 at 5:41
  • What matters is the value you entered at the read prompt, not the type. In a shell there is only one type that is a first class citizen - strings. – the_velour_fog May 13 '17 at 5:51
2

Generally speaking quotes are used to preserve the literal meaning of values and to avoid the interpreter doing transformations on special characters and other operations, such as parameter expansion and word splitting.
If you are using " to quote words, variables will be expanded still, but no word splitting will be performed.
Word splitting is the process of the shell taking a string and - conceptually breaking it up into different words, or tokens.
So if you entered this at the read prompt

bangalore data center

you command would be expanded like so:
With quotes

grep -iEr "$acl" ~/sync-configs/"$dc"/configs/*

becomes

grep -iEr bangalore data center ~/sync-configs/"$dc"/configs/*
          ^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            pattern argument      File/s argument to grep
            to grep

Without quotes

grep -iEr $acl ~/sync-configs/"$dc"/configs/*

becomes

grep -iEr bangalore data center ~/sync-configs/"$dc"/configs/*
          ^^^^^^^^^ |^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            pattern |    File/s argument to grep

note: in the above $dc would have also been expanded.

  • For clarity, it might be good to show that $dc is also expanded at the same time. – ilkkachu May 13 '17 at 10:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.