Nowe posty

Autor Wątek: Autoaktualizacja Debiana  (Przeczytany 1819 razy)

aston.marcin

  • Gość
Autoaktualizacja Debiana
« dnia: 2015-01-31, 14:28:39 »
Cześć

Napisałem prosty skrypt do automatycznej aktualizacji Debiana Stable:
#!/bin/sh
data="Aktualizacja z dnia `date`"
echo "$data\\n" > /tmp/aktualizacja
apt-get update > /dev/null
echo "........:::::::: Czyszczenie ::::::::........" >> /tmp/aktualizacja
apt-get autoremove -y >> /tmp/aktualizacja
echo "\\n" >> /tmp/aktualizacja
apt-get autoclean -y >> /tmp/aktualizacja
echo "\\n........:::::::: Uaktualnianie ::::::::........" >> /tmp/aktualizacja
apt-get dist-upgrade -y -o APT::Get::Show-Upgraded=true >> /tmp/aktualizacja
mail -s "$data" root < /tmp/aktualizacja
#rm /tmp/aktualizacja
Skrypt uruchamiany jest przez crona codziennie o 18:00
# m h dom mon dow user  command
0 18    * * *   root    /root/aktualizacja
Skrypt funkcjonuje prawidłowo, jednak w połączeniu z cronem posiada pewną osobliwość, jeśli chodzi o raportowanie swojego działania. Posłużę się tu przykładami:
1) brak pakietów do zaktualizowania, dostaję jednego maila od roota o mniej więcej takiej treści:
Aktualizacja z dnia sob, 31 sty 2015, 14:13:45 CET

........:::::::: Czyszczenie ::::::::........
Czytanie list pakietów...
Budowanie drzewa zależności...
Odczyt informacji o stanie...
0 aktualizowanych, 0 nowo instalowanych, 0 usuwanych i 0 nieaktualizowanych.


Czytanie list pakietów...
Budowanie drzewa zależności...
Odczyt informacji o stanie...

........:::::::: Uaktualnianie ::::::::........
Czytanie list pakietów...
Budowanie drzewa zależności...
Odczyt informacji o stanie...
0 aktualizowanych, 0 nowo instalowanych, 0 usuwanych i 0 nieaktualizowanych.
2) Są pakiety do zaktualizowania. Dostaję 2 listy: jeden od roota z outputami komend apt-get i drugi od demona crona z różną treścią. Na przykład po aktualizacji jądra:
Odczytywanie dzienników zmian...
Examining /etc/kernel/postrm.d .
run-parts: executing /etc/kernel/postrm.d/initramfs-tools 3.2.0-4-amd64 /boot/vmlinuz-3.2.0-4-amd64
run-parts: executing /etc/kernel/postrm.d/zz-update-grub 3.2.0-4-amd64 /boot/vmlinuz-3.2.0-4-amd64
Running depmod.
Examining /etc/kernel/postinst.d.
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.2.0-4-amd64 /boot/vmlinuz-3.2.0-4-amd64
update-initramfs: Generating /boot/initrd.img-3.2.0-4-amd64
run-parts: executing /etc/kernel/postinst.d/pm-utils 3.2.0-4-amd64 /boot/vmlinuz-3.2.0-4-amd64
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.2.0-4-amd64 /boot/vmlinuz-3.2.0-4-amd64
Generating grub.cfg ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-3.2.0-4-amd64
Found initrd image: /boot/initrd.img-3.2.0-4-amd64
done
po aktualizacji libc i zależności:
Odczytywanie dzienników zmian...
Generating locales (this might take a while)...
  pl_PL.ISO-8859-2... done
  pl_PL.UTF-8... done
Generation complete.
a przy mniejszych pakietach jedną linię:
Odczytywanie dzienników zmian...
Sytuacja wygląda tak, jakby w "konsoli" zostawał pewien tekst i cron musiał go przesyłać mailem. Co jest dziwne, zważywszy na to, że przekierowuje wszystkie znaczące wyjścia do /tmp/aktualizacja.
Czy potraficie wytłumaczyć zachowanie crona w tej sytuacji?

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 2988
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Autoaktualizacja Debiana
« Odpowiedź #1 dnia: 2015-01-31, 15:59:46 »
No właśnie nie przekierowujesz wszystkiego. Każdy program ma dwa "wyjścia", stdout i sterr. Na stdout idą zwykłe komunikaty (printf-y, echo-a, itp) a na stderr komunikaty błędów czy diagnostyczne.

I teraz jest tak - cron monitoruje oba wyjścia. Ty przekierowujesz do pliku wyjście stdout, więc cron go "nie widzi". Jeżeli program w czasie pracy nie wyświetli żadnych komunikatów na stderr, to cron stwierdza, że nic nie ma do wysłania i dostajesz maila tylko z twojego skryptu. Jednak jeżeli któryś program wyświetli coś na stderr, to cron to zobaczy i po skończeniu twojego skryptu (który wyśle mail z zawartością stdout) wyśle drugiego maila, z zawartością stderr.

Masz zatem dwie drogi:
* Albo przekierowujesz wszystko do pliku, za pomocą &>> (Zamiast >>). Wtedy cron nic nie zobaczy, więc nie wyśle drugiego maila
* Albo NIC nie przekierowujesz i nie wysyłasz nic w skrypcie, cron zobaczy wszystko i sam, automatycznie przyśle maila.
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

aston.marcin

  • Gość
Autoaktualizacja Debiana
« Odpowiedź #2 dnia: 2015-01-31, 16:20:27 »
OK, dzięki wielkie za sugestie.