Home > Back-end >  Why do I need a leading space in this BASH script?
Why do I need a leading space in this BASH script?

Time:04-05

Using this script to confirm a macOS Config Profile is installed

#!/bin/bash

NAME="ApplicationName - Config Profile"
profiles=$(profiles -C -v | awk -F: '/attribute: name/{print $NF}' | grep "$NAME")

if [ "$profiles" == " $NAME" ]; then
    echo "Profile exists"
else
    echo "Profile does not exist"
fi

If I don't have the leading space in the conditional (the space before $NAME) the conditional is wrong.

"$profiles" == "$NAME"

This returns "Profile does not exist"

"$profiles" == " $NAME"

This returns "Profile exists"

I can even echo $NAME and $profiles, they echo exactly the same, but the if conditional is different depending on that space. Why is this?

CodePudding user response:

Since you are changing the field separator in the awk command to be a colon, any whitespace will not be considered as a field separator, and so the whitespace will be printed with the print $NF statement. Grep also will not strip the whitespace, so "$profiles" really does contain a space at the beginning. If you put double quotes around $profiles when you echo it, you should see that there is a preceding space. For a bash script, it is usually recommended to use double brackets for if statements, e.g. if [[ $profiles == $NAME ]]; then (The double brackets won't solve this problem, but they are safer than single brackets.)

One solution would be to change the grep to another awk invocation:

profiles=$(profiles -C -v | awk -F: '/attribute: name/{print $NF}' | awk '/'"$NAME"'/ {$1=$1; print $0}')

The above will result in leading whitespace being removed.

CodePudding user response:

I'm pretty sure that profiles does contain a leading space (have a look at with echo "'$profiles'", which should make the space visible). However, I find the whole logic of your program problematic. You basically want to test, whether the input contains a line attribute: name ..... $NAME. In this case, you could do this simply as, i.e.

if profiles -C -v|grep -q "attribute: name.*: *$NAME$"
then
  echo Profile $NAME exists
fi

This assumes that NAME does not contain characters with special meaning in a regexp. If this can not be guaranteed, you would can write i.e.

if profiles -C -v|grep "attribute: name"| grep -Fq "$NAME"
then
  ...

This does not catch the requirement that $NAME must be at the end of the line. If this is really important to you (I don't know the possible variety in your input data), you could do the entire matching within awk (and set the exit status accordingly). The point is that for testing the existence of a certain profile name, you don't need to extract that name itself.

UPDATE: Incorporating remarks from tripleee

  • Related