Linuxmuster-client: Sinnvolleres "shutdown" script

#!/bin/bash                                                                                                                                                                              
## Script created by Rainer Rössler (roesslerrr-at-web.de)                                                                                                                               
## Modified by Robin Schneider <ypid@riseup.net>                                                                                                                                         
## Modified by Tobias Küchel <devel@zukuul.de> 2019                                                                                                                                      
## License: Free Software (License GPLv3)                                                                                                                                                

export LANG="de_DE.utf8"
export PATH="/usr/bin:/sbin:/bin"

TARGET_USER="$(who | grep 'tty' | tail --lines 1 | cut --fields 1 --delimiter ' ')"
run_in_user_context="sudo -u ${TARGET_USER}"

## Prüfen, ob ein Benutzer angemeldet ist; wenn nein shutdown, wenn ja...                                                                                                                
USERCOUNT=$(who | wc -l)
if [ $USERCOUNT -eq 0 ]; then
    shutdown -h now
else
    ## Frage an den Benutzer ob das Herunterfahren abgebrochen werden soll.                                                                                                              
    (   
        for i in `seq 0 1 100`; do echo $i ; sleep 3 ; done
    ) | 
        $run_in_user_context /usr/bin/zenity --progress --auto-close --text="Der PC wird in 5 Minuten heruntergefahren, wenn nicht abgebrochen wird." --title="PC-Abschaltung?"
    STATUS=$?
    if [ $STATUS -eq 1 ]; then ## Nicht herunterfahren                                                                                                                                   
        exit 0
    else
        /sbin/shutdown -h now
    fi
fi

exit 0

grafik

Ich hoffe man sieht, wenn man will, warum das besser ist, als der bisherige check-shutdown. Der bringt meine Kollegen zur WEißglut (vor allem seit wir schon letztes Jahr den meinigen hatten).

Viel Spass damit.
Tobias

1 Like

Achso, wermutstropfen: Ich habe es nicht geschafft, ein always-on-top window zu erstellen, auch nicht hiermit:

Always on top ist ein bisschen tricky. Das hängt zum großen Teil vom Window Manager ab. Böse zungen würden behaupten wenn man da was anständig konfigurierbares verwendet ,kwin * hust*, dann lässt sich das auch realisieren.

Vielleicht kannst du mit der Info was anfangen. Generell sollte sich das mit wmrctl mit jedem Window Manager bewerkstelligen lassen, ähnlich der zweiten Lösung hier:

Hallo Tobias!
Rufst du das Script per Cronjob unter Ubuntu 18.04 auf?
Mit welchem EIntrag?
Das klappt bei mir nicht.
Gruß - Rainer

Hallo Tobias!

Das mit dem user-context (sudo -u USER) hat bei mir nicht funktioniert. Vermutlich hat etwas gefehlt.

Ich habe daher eine zusätzliche logon-Datei „/etc/linuxmuster-client/login.d/60_desktopanzeige-cronjob-root.sh“ erstellt mit dem Inhalt „/usr/bin/xhost +local:root“.
Außerdem habe ich das Script angepasst (Es heißt bei mir /usr/bin/check-shutdown).
Der zenity-Aufruf ist nun ohne $run_in_user_context eingetragen (/usr/bin/zenity --progress --auto-close --text=„Der PC wird in 5 Minuten heruntergefahren, wenn nicht abgebrochen wird.“ --title=„PC-Abschaltung?“) und die Zeilen weiter oben zur Belegung der Variablen auskommentiert (#TARGET_USER= und #run_in_user_context ).

Zur Vollständigkeit, falls es jemand nachbauen nmöchte:
Der Cronjob-Eintrag in „/etc/cron.d/linuxmuster-client-extras“ heißt „0 20 * * * root DISPLAY=:0 /usr/bin/check-shutdown“ (für einen shutdown um 20 Uhr).
Und das shutdown-Script muss natürlich ausführbar sein (# chmod +x /usr/bin/check-shutdown ).

So funktioniert es bei mir.

Gruß - Rainer

Hallo,

ich habe meine Lösung hier schon einmal veröffentlicht:

Das Anzeigen der Restzeit alle 3 Sekunden mittels notify ist recht auffällig für den Benutzer. „Always on top“ des zenity-Fensters habe ich auch nicht hin bekommen.

Gestartet wird das Skript in meiner LMN V6.1 genau wie das original-Skript auch über
/etc/cron.d/linuxmuster-client-extras

# ----------------------------------------
# Shutdown this host, if user confirms GUI message
# Please uncomment to activate!
# shutdown at 00:00
0 0 * * * root DISPLAY=:0 /usr/bin/check-shutdown

Gruß
Stefan

Manipuliert wird die Shutdown-Zeit dann per postsync. Hier ein Beispiel, wie die ersten 4 Zeichen des Rechnernamens zur Zuordnung einer Shutdown-Zeit verwendet werden.

#####################################################
# Shutdown nach Rechnername #########################
#####################################################

shutdowntype="${HOSTNAME:0:4}"
echo $shutdowntype

case $shutdowntype in 
 adm-|img-)
  echo Shutdown nicht verändert
   ;;
 aul-|hau-)
  echo Shutdown sehr spät
  sed -i 's#shutdown at 00:00#shutdown angepasst durch postsync#g' /mnt/etc/cron.d/linuxmuster-client-extras
  sed -i 's#.*/usr/bin/check-shutdown#0 0-2 *\ *\ *\ root DISPLAY=:0 /usr/bin/check-shutdown#g' /mnt/etc/cron.d/linuxmuster-client-extras
   ;;
 men-|mob-|pla-|edv-)
  echo Shutdown spät
  sed -i 's#shutdown at 00:00#shutdown angepasst durch postsync#g' /mnt/etc/cron.d/linuxmuster-client-extras
  sed -i 's#.*/usr/bin/check-shutdown#0 20-23,0-2 *\ *\ *\ root DISPLAY=:0 /usr/bin/check-shutdown#g' /mnt/etc/cron.d/linuxmuster-client-extras
   ;;
 *)
  echo Shutdown normal
  sed -i 's#shutdown at 00:00#shutdown angepasst durch postsync#g' /mnt/etc/cron.d/linuxmuster-client-extras
  sed -i 's#.*/usr/bin/check-shutdown#0 17-23,0-2 *\ *\ *\ root DISPLAY=:0 /usr/bin/check-shutdown#g' /mnt/etc/cron.d/linuxmuster-client-extras
   ;;
esac

Ich hab das Script von Tobias mal so erweiter, dass das Fenster auch wirklich always on top ist:

#!/bin/bash
## Script created by Rainer Rössler (roesslerrr-at-web.de)
## Modified by Robin Schneider <ypid@riseup.net>
## Modified by Tobias Küchel <devel@zukuul.de> 2019
## Modified by Andreas Till<andreas.till@netzint.de> 2019
## License: Free Software (License GPLv3)

export LANG="de_DE.utf8"
export PATH="/usr/bin:/sbin:/bin"

TARGET_USER="$(who | grep 'tty' | tail --lines 1 | cut --fields 1 --delimiter ' ')"
run_in_user_context="sudo -u ${TARGET_USER}"

## Prüfen, ob ein Benutzer angemeldet ist; wenn nein shutdown, wenn ja...
USERCOUNT=$(who | wc -l)
if [ $USERCOUNT -eq 0 ]; then
    echo DEBUG herunterfahren
    shutdown -h now

else
    ## Frage an den Benutzer ob das Herunterfahren abgebrochen werden soll.
    (
        for i in `seq 0 1 100`; do echo $i ; sleep 3 ; done
    ) |
        $run_in_user_context /usr/bin/zenity --progress --auto-close --text="Der PC wird in 5 Minuten heruntergefahren, wenn nicht abgebrochen wird." --title="PC-Abschaltung?" & sleep 1 && wmctrl -r "PC-Abschaltung?" -b add,above
        wait $(jobs -p)
    STATUS=$?
    if [ $STATUS -eq 1 ]; then ## Nicht herunterfahren
        echo DEBUG: nicht herunterfahren
        exit 0
    else
        echo DEBUG: herunterfahren
        /sbin/shutdown -h now

    fi
fi

exit 0

Bitte mal testen ob das funktioniert.

EDIT: Unnötige Leerzeichen entfernt…
EDIT2: Header wieder hinzugefügt.

1 Like

Hallo,

ich habe hier seit etwa 8 Jahren das folgende Skript laufen:

 #!/bin/bash

# Session to search for
SEARCHSESSION="xfce4-session"
# where is zenity?
ZENITY=/usr/bin/zenity
# check file
MANUAL=/tmp/shutd-$(date +%s)
rm -rf $MANUAL
# skriptname
SELF=$0
# Aktion?
ACTION=$1
if [ x$ACTION == "x" ]; then
        ACTION="doit"
fi

function notify_user {
        (
        for ((i=1; i<=100; i++)); do
            echo $i; sleep 1
        done
        ) |
        $ZENITY --progress \
          --title="Computer ausschalten" \
          --text="Der Computer wird demnächst ausgeschaltet.\n\nDabei gehen alle nicht gespeicherten Änderungen an geöffneten Dateien\nund Dokumenten verloren.\n\nWenn Sie das nicht wollen, klicken Sie auf\nn
Abbrechen und schalten den Computer aus,\nwenn Sie mit Ihrer Arbeit fertig sind." \
          --auto-close \
          --percentage=0

        if [ ! $? -eq 0 ] ; then
                touch $MANUAL
        fi
}

if [ $ACTION == "dialog" ]; then
        notify_user
        exit 0
fi

for pid in $(pgrep $SEARCHSESSION); do
        DY=$(grep -z DISPLAY /proc/$pid/environ)
        UR=$(grep -z USER /proc/$pid/environ | cut -d= -f2)
        #echo "$DY $UR"
        su - $UR -c "$DY $SELF dialog"
done


if [ -f $MANUAL ]; then
        rm $MANUAL
else
        /sbin/shutdown -h now
fi

Das Problem mit den Zeiten löse ich einfach dadurch, dass die Client vom Server ausgeschaltet werden: der Benutzer root des Servers kann auf alle Clients drauf per SSH (key ist im Image). dann kann man die Rechner einfach via Cronjob auf dem Server ausschalten. On Top war das schon immer.

Wichtig: Man muss je nach verwendetem Flavour die zu suchende Session ganz am Anfang anpassen, damit das Skript korrekt prüft, ob jemand angemeldet ist. War hier ein bissle blöd beim Wechseln von Unity nach xfce :wink:

VG

Frank