I am trying to write a simple shell script to hide/show my desktop icons but I get the error "hidedesktopicons.sh: line 1: [[gsettings: command not found" when I try to run it?

I searched for how to use if then statements in a shell script. I added "fi"

enter code here

cat hidedesktopicons.sh 
if [[gsettings get org.mate.background show-desktop-icons = true]]
then gsettings set org.mate.background show-desktop-icons false
else gsettings set org.mate.background show-desktop-icons true
fi

I expect the icons to hide/unhide. I get the error "hidedesktopicons.sh: line 1: [[gsettings: command not found"

2 Answers

0
chepner On Best Solutions

The immediate problem is that you need whitespace after [[:

if [[ gsettings ...

The next problem is that you need to use a command substitution to capture the output of gsettings so that you can compare it to true:

if [[ $(gsettings get org.mate.background show-desktop-icons) = true ]]
then gsettings set org.mate.background show-desktop-icons false
else gsettings set org.mate.background show-desktop-icons true
fi

You might want to define a pair of functions to reduce some of the repetitiveness of this code:

get_icon_status () {
  gsettings get org.mate.background show-desktop-icons
}

set_icon_status () {
  gsettings set org.mate.background show-desktop-icons "$1"
}

if [[ $(get_icon_status) = true ]]; then
  set_icon_status false
else
  set_icon_status true
fi
0
kvantour On

Bash, in contrast to common programming languages, does not really have keywords for true and false. So if a program returns in a terminal the string value "true" it will just consider it to be a string of the same nature as 'foo" or "bar". The if-statement in bash does not evaluate what is returned by a command, it evaluates the return-code of a command.

if list1; then list2; else list3; fi

Which should be read as: if list1 is executed and has a return-code 0, it will execute list2, otherwise list3.

To fully demonstrate I use the following confusing command:

$ if echo true; then echo yes; else echo no; fi
true
yes
$ if echo false; then echo yes; else echo no; fi
false
yes

As you see, echo true returns the value true and echo false the value false but both return yes which just indicates that the echo command executed successfully. If we know make use of the binaries true and false

$ which true; true; echo $?
/usr/bin/true
0
$ if true; then echo yes; else echo no; fi
yes
$ which false; false; echo $?
/usr/bin/false
1
$ if false; then echo yes; else echo no; fi
no

One of the common commands used in the if-statement is the test command, commonly written as [ EXPRESSION ] or the bash compound command [[ EXPRESSION ]] , both having a return code of 0 if EXPRESSION evaluates to true, and 1 if EXPRESSION is false. These commands can be used to do string evaluations as presented by the OP.

if [[ $(gsettings get org.mate.background show-desktop-icons) == true ]]
then gsettings set org.mate.background show-desktop-icons false
else gsettings set org.mate.background show-desktop-icons true
fi