Bash Shell Scripts: Although apt-get update Failed, The Exit Status Is 0, Writing Automatic Update Scripts With Utilizing Exit Staus

I am trying to write automatic update and upgrade script.

I want to utilize command execution's exit status,

but even if the apt-get update command fails, it returns exit status 0.

So my script can not achieve the purpose.

QUESTIONS===========

Why does apt-get update return 0, I want to get other numbers rather than 0 when the command fails though?

And to make my script achieve the purpuse, how could I modify it?

=====================

Thank you for your reading!

Here is the update part of my script;

#!/bin/bash -x 

### Variables
count=
command_result=""

### Main

echo "$(LC_TIME=en_US.UTF-8 date)" >> log_update

until [ "$count" = "10" ] || [ "$command_result" = "done" ]; do

    sudo apt-get update

    if [ "$?" = "0" ]; then
        echo "Update succeeds." >> ~/log_update
        command_result="done"
    fi

    count=$((count + 1)) 

done

if [ "$command" != "done" ]; then
    echo "Time Out: Update FAILED! Solve Problem." >> log_update
fi
0
задан 13 August 2020 в 21:44

1 ответ

To understand why apt or apt-get returns 0, even when you encounter an error, you should first know that these commands are also a program which was developed by some programmer. Hence the values returned to the terminal are also decided by the developer of the program.

The only case when I have seen apt not work is when it is executed without sudo
Here is a snippet when apt is executed without superuser privilege :

mars@HP-Notebook:~/Desktop/Practice/cpp$ apt update
Reading package lists... Done
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
W: Problem unlinking the file /var/cache/apt/pkgcache.bin - RemoveCaches (13: Permission denied)
W: Problem unlinking the file /var/cache/apt/srcpkgcache.bin - RemoveCaches (13: Permission denied)
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
100

As you can see that the exit code is not 0. Hence we can conclude that command or program was not executed.
Let's take another case, when there is no internet connection :

mars@HP-Notebook:~/Desktop/Practice/cpp$ sudo apt update
Err:1 http://security.ubuntu.com/ubuntu bionic-security InRelease
  Could not resolve 'security.ubuntu.com'
Err:2 http://dl.google.com/linux/chrome/deb stable InRelease                                                   
  Could not resolve 'dl.google.com'
Err:3 http://in.archive.ubuntu.com/ubuntu bionic InRelease                                                     
  Could not resolve 'in.archive.ubuntu.com'
Err:4 https://download.sublimetext.com apt/stable/ InRelease                     
  Could not resolve 'download.sublimetext.com'
Err:5 http://in.archive.ubuntu.com/ubuntu bionic-updates InRelease
  Could not resolve 'in.archive.ubuntu.com'
Err:6 http://in.archive.ubuntu.com/ubuntu bionic-backports InRelease
  Could not resolve 'in.archive.ubuntu.com'
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.
W: Failed to fetch http://in.archive.ubuntu.com/ubuntu/dists/bionic/InRelease  Could not resolve 'in.archive.ubuntu.com'
W: Failed to fetch http://in.archive.ubuntu.com/ubuntu/dists/bionic-updates/InRelease  Could not resolve 'in.archive.ubuntu.com'
W: Failed to fetch http://in.archive.ubuntu.com/ubuntu/dists/bionic-backports/InRelease  Could not resolve 'in.archive.ubuntu.com'
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease  Could not resolve 'security.ubuntu.com'
W: Failed to fetch https://download.sublimetext.com/apt/stable/InRelease  Could not resolve 'download.sublimetext.com'
W: Failed to fetch http://dl.google.com/linux/chrome/deb/dists/stable/InRelease  Could not resolve 'dl.google.com'
W: Some index files failed to download. They have been ignored, or old ones used instead.
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0

As you see the exit code is 0 even though we encountered an error. The reason for this is that the program or command did execute successfully. However it was unable to update the package lists for upgrades of packages that need upgrading.

The only explanation for this is that the developer of apt command didn't consider the failed to update the package list as an error to stop the command itself and return an error exit status code. Instead the command provides warnings after execution.

To give a better understanding I am going to take an example of C program:

#include<stdio.h>

int main(int argc, char *argv[]) {
    if(argc==2) 
        printf("Welcome Master %s\n", argv[1]);
    else {
        fprintf(stderr, "Usage : %s <name>\n", argv[0]);
        return 1;
    }
    return 0;
}

Output:

mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman
Usage : ./batman <name>
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
1
mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman Bruce
Welcome Master Bruce
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0

As you can see there are 2 different exit status code, because as a programmer I considered that command executed with no argument is an error and should be terminated with exit code "1". ( I could choose any value ). And if command executed successfully I returned "0" as exit status code which signifies that no error was encountered.

Lets take another example :

#include<stdio.h>

int main(int argc, char *argv[]) {
    if(argc==2) 
        printf("Welcome Master %s\n", argv[1]);
    else
        printf("ERROR!!\nUsage : %s <name>\n", argv[0]);

    return 0;
}

Output:

mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman_error 
ERROR!!
Usage : ./batman_error <name>
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0
mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman_error Bruce
Welcome Master Bruce
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0

Again the same program but this time the programmer ( i.e. me ) did not consider to terminate the program with a different exit status code. Hence even though terminal prints an output of Error the exit status code is "0".

Conclusion

От разработчика программы зависит, какое значение вернуть (т.е. код состояния выхода) в зависимости от ситуации.
Я надеюсь, что это проясняет концепцию кода статуса выхода.

Suggestion on your bash script

I saw that you are using a loop which will try to execute apt update command 10 times if it was not executed successfully. To be honest if it didn't work the first time it won't work the next 9 times as well. Hence creating a loop is just pointless.

Now if you want to check for an error use nested if-else conditions. You can check for status code on first level and to check for error with execution of apt on second level (i.e. with exit code "0" ) you can use something like :

sudo apt update | grep "Err"

if grep was able to fetch a line then store that as an error in your log file, else update was successful.

1
ответ дан 21 August 2020 в 08:00

Другие вопросы по тегам:

Похожие вопросы: