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 „Gefällt mir“

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.

2 „Gefällt mir“

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

Hej,
Unsere Notebooks mit dem 20.04er-Image fahren nicht mehr automatisch herunter.
Ich vermute, dass das mit dem Standby zusammenhängt und 20.04 die Geräte so schlafen legt, dass der cronjob nicht ausgeführt wird.

Welche Einstellungen benutzt ihr denn unter org.gnome.settings-daemon.plugins.power?
Ich habe da org.gnome.settings-daemon.plugins.power lid-close-ac-action -> suspend
stehen. Daran wird’s vermutlich liegen.

Ich tue mich aber auch schwer damit, den Suspendmodus auszuschalten (blank), wegen Überhitzung etc. Die Geräte sind in einem kleinen Möbel ohne Lüftung etc. untergebracht…

Wie löst ihr das Problem?
Gibt es z.B. eine Möglichkeit die Geräte zeitgesteuert wieder aus dem suspend-Modus auszuwecken (von lokal oder vom Server aus)? Also z.B. kurz bevor check-shutdown ausgeführt wird?

Grüße
Michael

Hi. Warum reicht dir das nicht?
Ich habe gerade nochmal auf unserem 20.04er Client nachgesehen. Dort steht unter /etc/cron.d/linuxmuster-client :

# ----------------------------------------
# Shutdown this host, if user confirms GUI message
# Please uncomment to activate!
# shutdown at 18:00 and further every 30 min until 23:30
*/30 18-23    * * *    root    DISPLAY=:0 /usr/local/bin/check-shutdown

Bei Dir nicht (mehr)?

Viele Grüße,
Michael

Hej,
dochdoch. Das steht da schon. Aber es passiert halt nicht. Ich habe gestern abend gesehen, dass Notebooks,

  • bei denen jemand angemeldet war
  • bei denen der Anmeldescreen zu sehen war,

sauber herunterfuhren.

Die anderen Geräte im Standby (Deckel geschlossen), sind aber nicht heruntergefahren.

Das ist schlecht, weil die Geräte einfach nicht für 24/7-Nutzung gemacht sind. Es kamen Klagen, dass die „eingefroren“ sind und man nichts mehr machen konnte…

Ich will irgendwie erreichen, dass auch Geräte im Standby abends runterfahren…

Grüße
Michael

Hallo,

… Standby ausschalten…

LG

Holger

Hej Holger,
danke schon mal fürs Mitdenken!

Ich war halt vorsichtig, weil ja die Überhitzungsgefahr schon da ist / war. (Siehe auch die Warnung hier unter „Hibernate und Suspend deaktivieren“)

Nach viel Recherche und Ausprobieren habe ich nun in /etc/systemd/sleep.conf den Schalter AllowSuspend auf no gesetzt.
Das tut hoffentlich, was es tun soll - jetzt muss ich nur noch beobachten, wie warm das Gerät auf die Weise wird.

Andere Versuche haben alle nicht gut funktioniert:

  • Einstellungen per gsettings / dconf-editor (unter org.gnome.settings-daemon.plugins.power) hatten gar keinen Effekt
  • Das hat den Standby im Anmeldebildschirm nicht verhindert.
  • Das war zu brachial: Die Lüfter haben angefangen zu arbeiten, kurz nachdem der Deckel geschlossen war und das Notebook wurde recht schnell ziemlich warm.

Falls jemand für den ubuntu 20.04-Client eine bessere Lösung kennt, würde mich das interessieren.
Ansonsten würde ich sagen Knopf dran. Passt.

Grüße
Michael

Hi Michael.

Gut möglich, dass ich die Dramatik des Problems nicht ganz erfasst habe – mein Lenovo-Laptop zu Hause wird seit x Jahren durch Druck auf den Power-Knopf in den Suspend-Mode versetzt. Das hat bisher nie irgendwelche Probleme gemacht.

Unter KDE/Plasma sieht die Einstellung so aus:

Da könnte man also auch einstellen, dass der Rechner herunterfahren soll, wenn die Powertaste gedrückt wird. Wie/ob das unter Ubuntu (ohne KDE/Plasma) läuft, weiß ich nicht – müsste aber doch ähnlich einfach gehen?

Viele Grüße,
Michael

Hej Michael,
Der Standbymodus ist (war) auch nicht das Problem.
Nur: Im Standby wird der cron-job mit dem shutdown-skript (natürlich) nicht ausgeführt. Und das führte dazu, dass die Geräte tagelang ungesynct im Standby waren und oft nicht mehr richtig aufwachten.

Mein Ziel war also, den Standby zu verhindern, damit das shutdown-skript wieder funktioniert - und das auf eine Weise, dass die Geräte nicht überhitzen…

Ich denke, ich habe mit dem o.g. AllowSuspend=no eine gute Einstellung gefunden und bin nun am testen, wie heiß die Geräte damit werden. Die anderen Tests habe ich hier nur dokumentiert, falls jemand anderes am gleichen Punkt steht.

Grüße
Michael

Ach darum ging es dir … das hatte ich offenbar überlesen.
Aber ist doch gut, wenn Du eine Lösung gefunden hast.
Viele Grüße,
Michael

Hej,
im neuen Linuxclient (linuxmuster-linuxclient7) funktioniert das script bei uns so nicht mehr:

Grund: who hat früher angemeldeterUser :tty ausgegeben. Jetzt steht da bei angemeldeterUser :0 und entsprechend wird ${TARGET_USER} nicht richtig belegt.

TARGET_USER="$(who | grep 'tty' | tail --lines 1 | cut --fields 1 --delimiter ' ')"

Die erste Idee grep 'tty' durch grep '0' zu ersetzen, geht so lange gut, bis sich jemand via „Switch User“ abmeldet…

@Tobias : Warum überhaupt der grep? Würde das nicht reichen?

TARGET_USER="$(who | tail --lines 1 | cut --fields 1 --delimiter ' ')"

Oder gibt es Situationen, wo who andere user aufführt, als die an der GUI angemeldeten?

Grüße
Michael

Hi Michael,
ich habe keine Ahnung (mehr). Vor allem habe ich noch nicht den neuen linuxclient bei mir am Laufen.
Es gibt sicher noch die Möglichkeit, dass sich user an der Konsole anmelden, zumindest bei mir so. Beim standard-linuxclient ist das vielleicht deaktiviert.

Daher: deine Zeile klingt gut, warum nicht?
VG, Tobias

Hi Michael,
ich habe erst jetzt in den Artikel reingeschaut. Vielleicht hast du ja schon alles gelöst…

Falls nicht, so haben wir’s gelöst:
Bei uns weckt der Server alle Clients ca. 5 Minute bevor die Rechner einen Shutdown machen auf. Dafür läuft folgendes cron-Skript:

#!/bin/bash
/usr/sbin/linbo-remote -r raum1 -w 1 -b 1
/usr/sbin/linbo-remote -i raum2 -w 1 -b 1

Dadurch gehen alle Rechner aus dem Standby und punkt 18:00 fahren sie wieder runter.

Und morgens ab 7:00 weckt das Skript die Rechner auf. Fünf Minuten nachdem die Rechner hochgefahren sind gehen Sie in den Standby. Sobald jetzt ein Kollege die Maus bewegt oder eine Taste drückt ist der Rechner in Nullkommanix einsatzbereit.

Was auch geht, ist, dass sich die Rechner jeden Montag morgen restaurieren.

Gruß,
Mathias