Μελετώ το περιεχόμενο αυτού του αρχείου preinst που εκτελεί το σενάριο πριν το πακέτο αποσυμπιεστεί από το αρχείο Debian (.deb).
Το σενάριο έχει τον ακόλουθο κώδικα:
#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
if [ -d /usr/share/MyApplicationName ]; then
echo "MyApplicationName is just installed"
return 1
fi
rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section
Το πρώτο μου ερώτημα αφορά τη γραμμή:
set -e
Νομίζω ότι το υπόλοιπο σενάριο είναι αρκετά απλό: Ελέγχει αν ο διαχειριστής πακέτων Debian/Ubuntu εκτελεί μια λειτουργία εγκατάστασης. Αν ναι, ελέγχει αν η εφαρμογή μου έχει μόλις εγκατασταθεί στο σύστημα. Αν έχει, το σενάριο εκτυπώνει το μήνυμα "MyApplicationName is just installed" και τελειώνει (return 1
σημαίνει ότι τελειώνει με "σφάλμα", έτσι δεν είναι;).
Αν ο χρήστης ζητά από το σύστημα πακέτων Debian/Ubuntu να εγκαταστήσει το πακέτο μου, το σενάριο διαγράφει επίσης δύο καταλόγους.
Είναι αυτό σωστό ή μου διαφεύγει κάτι;
Από το help set
:
-e Exit immediately if a command exits with a non-zero status.
Αλλά θεωρείται κακή πρακτική από μερικούς (συγγραφείς των bash FAQ και irc freenode #bash FAQ). Συνιστάται η χρήση:
trap 'do_something' ERR
για να εκτελείτε τη συνάρτηση do_something
όταν εμφανίζονται σφάλματα.
Το set -e
σταματά την εκτέλεση ενός σεναρίου αν μια εντολή ή ένας αγωγός έχει σφάλμα - το οποίο είναι το αντίθετο από την προεπιλεγμένη συμπεριφορά του κελύφους, η οποία είναι να αγνοεί τα σφάλματα στα σενάρια. Πληκτρολογήστε help set
σε ένα τερματικό για να δείτε την τεκμηρίωση αυτής της ενσωματωμένης εντολής.
Σύμφωνα με το εγχειρίδιο bash - The Set Builtin, αν έχει οριστεί το -e
/errexit
, το κέλυφος τερματίζει αμέσως αν μια αγωγός που αποτελείται από μια απλή απλή εντολή, λίστα ή σύνθετη εντολή επιστρέψει κατάσταση μη μηδενική.
Από προεπιλογή, η κατάσταση εξόδου ενός αγωγού είναι η κατάσταση εξόδου της τελευταίας εντολής στον αγωγό, εκτός αν είναι ενεργοποιημένη η επιλογή pipefail
(είναι απενεργοποιημένη από προεπιλογή).
Σε αυτή την περίπτωση, ο αγωγός'ς επιστρέφει την κατάσταση της τελευταίας (πιο δεξιά) εντολής που εξέρχεται με μη μηδενική κατάσταση, ή μηδέν αν όλες οι εντολές εξέλθουν επιτυχώς.
Αν θέλετε να εκτελέσετε κάτι κατά την έξοδο, δοκιμάστε να ορίσετε το trap
, για παράδειγμα:
trap onexit EXIT
όπου onexit
είναι η συνάρτησή σας για να κάνετε κάτι κατά την έξοδο, όπως παρακάτω που εκτυπώνει το απλό stack trace:
onexit(){ while caller $((n++)); do :; done; }
Υπάρχει παρόμοια επιλογή -E
/errtrace
η οποία θα παγιδεύει στο ERR αντί για αυτό, π.χ:
trap onerr ERR
Παράδειγμα μηδενικής κατάστασης:
$ true; echo $?
0
Παράδειγμα μη μηδενικής κατάστασης:
$ false; echo $?
1
Παραδείγματα αρνητικής κατάστασης:
$ ! false; echo $?
0
$ false || true; echo $?
0
Δοκιμή με απενεργοποιημένο το pipefail
:
$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1
Δοκιμή με ενεργοποιημένο το pipefail
:
$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1