How to detect or return other than 0 code for $? upon software not installed (doesn't exist) detection?


#1

For example:

sudo apt purge -y firefoks will return 100.

E: Unable to locate package firefoks

However:

sudo snap remove gnome-calculators will return 0.

snap “gnome-calculators” is not installed

I think snapd should return an error status since it couldn’t find the package locally just like the good ol’ apt. This gives us more power to detect and write better scripts natively because there’s no way to differentiate either the package is actually not installed or doesn’t exist without using some additional hacks (awk, sed).

Edit: I wrote a short debloating script for Ubuntu 19.04 minimal but the error detection is pretty much useless. What do you think?

$! /bin/bash

function debloat ()
{
    local snap=(
        "gnome-calculatorsss"
        "gnome-calculator"
        "gnome-character"
        "gnome-logs"
        "gnome-system-monitor"
    )
    for ((i = 0; i < ${#snap[@]}; i++))
    do
        sudo snap remove ${snap[$i]} &> /dev/null
        if [[ $? -eq 0 ]]
        then
            echo -e "Removing '${snap[$i]}'... \e[1;32mdone\e[0m"
        else
            echo -e "Removing '${snap[$i]}'... \e[1;31mfailed\e[0m"
        fi
    done
}

debloat

#2

As a work-around, you could do snap list $THE_SNAP as that will return 1 if the snap isn’t installed locally.


#3

For the record, I disagree: after snap install foo, if foo is installed there was no error; after snap remove foo, if foo is not installed there was no error. That includes “it was already installed” in the first case, and “it was already not there” in the second.


#4

In other words, all you need to do once you have the snap array defined in your function is
snap remove "${snap[@]}". Anything more is … bloat.


#5

unless you want to use a non-bloated shell :wink:
(bash is a massive ressource hog for simple scripts and this code is very bash centric)


#6

Thanks for the participation in this discussion guys. Actually, I wrote the above code in less than a few seconds just as an example. I think we can simply use sudo snap remove gnome-calculator gnome-character gnome-logs gnome-system-monitor and there’s no need for the above codes that’s pretty much useless. I’m trying to demo how this error “not found” detection is useful to know instead of simply saying “yeah, I can’t find this package locally and I don’t think this remove command is a mistake”. I can’t explain it in a better way if we use the 1 liner above, it will show a “conflicting” error message log while another snapd seed is in progress hence, the loop in my previous example.

@ijohnson I don’t get what snap list $THE_SNAP is and how that can return 1 if it isn’t installed locally, where did you get that variable from anyway?

@chipaca As I mentioned above, you gave snapd a command to remove foo, but it couldn’t find it hence it thinks it did not find an error but I’m fine by that ideology. If so, how can you know that it isn’t installed at the first place? Like the above sudo apt purge, if it can’t find the package installed locally it will tell you an error exit code instead so we know for sure that package isn’t available and nothing can be removed hence the purge/remove command is invalid or “error” – or “soft-error” that’s rather subjective.

Also, your suggestion is the same as the one-liner code I wrote in reply to @ijohnson above. It works just fine but I don’t like the “conflicting” message log, not sure whether the process is simultaneously or queue but why that conflicting messages are even shown to begin with. I need to display the removal process notifcation individually hence the loop…

ogra I’m not so sure about resource hog, but I wrote the above codes to setup a few of my “quite powerful i7” home PCs for a custom Ubuntu installation with some other GNOME tweaks, dynamic wallpapers, etc. to make my life a little easy and removing those pre-installed snap apps are just a small part of the process. I wanted to create my own custom ISO but ended up creating this script instead since sometimes, I want a different setup and ask the end users using some zenity window for customization…

Thanks again! I appreciate your feedback.


#7

If for some reason other than removing the snap, you still need to detect if it’s installed you can use snap list. I just included $THE_SNAP as a placeholder for whatever snap name you have, for example:

$ snap list gnome-characters 
Name              Version               Rev  Tracking  Publisher   Notes
gnome-characters  v3.32.1+git2.3367201  296  stable    canonical✓  -
$ echo $?
0
$ snap remove gnome-characters 
gnome-characters removed
$ echo $?
0
$ snap remove gnome-characters 
snap "gnome-characters" is not installed
$ echo $?
0
$ snap list gnome-characters
error: no matching snaps installed
$ echo $?
1

#8

Ah, I see, this is a useful workaround. Thanks, really! But somehow, this requires an additional function/step to actually detect the existence first. So it means, I will have to check for the error code 1 (within the loop) first then only proceed to actually removing it if it exist. Why can’t they create this “detection” natively so I don’t have to do sudo snap list everytime and know it directly when I do sudo snap remove - did I get the logic wrong or what? sudo apt purge will return 100 but sudo snap remove will return 0 for this case and both are contradicting to each other.

Regardless, I will use your suggested solution. It won’t hurt my script to add an extra command, just maybe a few miliseconds :joy: — thanks a bunch!