Letzte Datei des Verzeichnisses ausführen NACH Autostart-(Skript)

  • Hallo liebe Community,


    ich habe einen Raspberry Pi 2 mit Raspbian (Jessie).
    Dieser ist an einem Monitor angeschlossen, auf dem täglich eine neue Präsentation laufen soll, die neue Präsentation wird immer gegen Abend erstellt. Die neue Präsentation für den nächsten Tag wird über eine Sambafreigabe in das Verzeichnis Bildschirmausgabe kopiert.
    Der Pi soll jede Nacht neugestartet werden und durch diesen Neustart soll, durch das Skript im Autostart, die zuletzt auf das Verzeichnis Bildschirmausgabe hinzugefügte Datei bzw. die Datei mit dem letzten Änderungsdatum, ausgeführt werden. Es handelt sich um eine LibreOffice Impress Präsentation mit der Dateiendung .odp





    @/home/pi/vnc.sh 1>/tmp/vnc.log 2>&1


    startet den VNC Dienst/Client (hierfür irrelevant)


    cd /home/pi/Bildschirmausgabe


    Das Verzeichnis mit der täglichen Präsentation



    ACTUAL=$(ls -t | head -1)


    Variable ACTUAL erzeugen und ihr festlegen, dass alle Dateien in einer Liste stehen und nach Datum sortiert sind, die Datei, die zuletzt geändert wurde, steht durch head -1 ganz oben.



    echo $ACTUAL


    Hier wird die Variable ACTUAL überprüft (aus Testzwecken für mich selber, um zu sehen, dass die Variable auch das richtige enthält)



    read a


    vergessen was read a macht, gehört zu echo...



    sudo rm -f /home/pi/Bildschirmausgabe
    @soffice -show /home/pi/Bildschirmausgabe/$ACTUAL


    Die erste Zeile ist einfach da, damit die 2. Zeile funktioniert, sie löscht nicht, bzw. kann nichts löschen, existiert einfach nur.
    Die zweite Zeile ist der Startbefehl für LibreOffice Impress, anstatt $ACTUAL stand dort a.ppt (ppt anstatt odp ist einfach so, weil der Befehl anscheinend so geht, die erste Zeile mit diesem rm macht auch wenig Sinn, habe ich aber aus dem Netz entnommen und wird anscheinend von vielen so verwendet (meine Testpräsentation heißt a.odp und liegt auf dem Verzeichnis Bildschirmausgabe).
    Dort steht jetzt halt eine Variable, im Autostart steht aber nirgendwo mehr, dass a.odp weiterhin nach einen Reboot gestartet werden soll, was aber passiert (die a.odp befindet sich noch im Verzeichnis Bildschirmausgabe, die zweite Präsentation heißt Vorlage.odp und befindet sich ebenfalls dort, sie würde für den nächsten Tag erstellt und auf /home/pi/Bildschirmausgabe kopiert, sie hat also das letzte Änderungsdatum und sollte laut ACTUAL=$(ls -t | head -1) oben in der Liste stehen, die Ausführung klappt halt einfach nicht, ich bin mir auch nicht sicher ob, das so überhaupt klappt, wie lautet denn der Befehl um etwas auszuführen?, sprich, der Befehl, um eine Präsentation über das Terminal aufzurufen und sie dann auf meinem Monitor als Slide Show/Präsentation zu sehen, ich habe Linux Server, die haben aber alle keine grafische Oberfläche, sprich der Raspberry Pi ist mir nicht neu aber ich weiß nicht ganz mit Befehlen umzugehen, die etwas grafisches darstellen sollen, bekomme das einfach nicht realisiert, kann mir jemand helfen, schrittweise oder auch nur erstmal mit dem Befehl, wie man eine Präsentation auszuführen kann, über Terminal Befehl, helfen?


    Mit freundlichen Grüßen
    Pi-Tight



    :danke_ATDE:

  • Wieso rebootest du? Dieses ständige Rebooten ist doch völlig unnötig. Lass doch einfach soffice killen und neu starten. Lass einfach ein Script via crontab jede Minute ausführen, prüf ob es eine Datei neuer als "heute 0800" gibt und starte die Präsentation dann neu.

  • Du kannst es dier doch einfacher machen:
    https://python-pptx.readthedocs.io/en/latest/
    Die Datei nach dem Datum bennenen an dem sie abgespielt werden soll.
    Dann den Pi anweisesn immder nach dem Datum zu schauen und dann die Datei mit dem Tagesdatum abzuspielen.
    z.b.
    Datei: 21-7-2020.odp
    Python Code:

    Code
    import time
    mytime="%d- %m- %Y"
    # Befel zum Abspielen(/home/pi/%.odp, % mytime)


    PS: http://www.forum-raspberrypi.d…entation-in-dauerschleife


    Keine Garantie auf nix.
    Alles ungetestet. Bitte korrigieren wenn falsch.


    !Thread reicht!



  • Vielen Dank für die Antwort, euch beiden, ich habe mich jetzt an den Befehlen von Berlin_pi orientiert und einen Crontjob eingestellt, der jede Stunde läuft und so sieht der Inhalt des Scriptes aus:


    import time
    mytime="%d- %m- %Y"
    sudo rm -f /home/pi/Bildschirmausgabe
    @soffice -show /home/pi/Bildschirmausgabe/%.odp, % mytime


    1. Zeile müsste die Zeit importieren
    2. Zeile legt Tag, Monat und Jahr fest, vom Computer !?!
    3. Zeile sollte die laufende Präsentation killen
    4. Zeile Ist für das starten von LibreOffice Impress und der Präsentation mit dem heutigen Datum als Dateinamen, ist der Befhl richtig angepasst?,
    früher sha er so aus: @soffice -show /home/pi/Bildschirmausgabe/a.ppt (ppt hat funktioneirt, obwohl es odp ist, habe den Befhl aus dem Internet)



    Vielen Dank für die gestrige Hilfe und liebe Grüße :)


  • Dein Dateiname ist present.sh , die Dateiendung ist zwar nicht wichtig aber sagt aus das es sich um ein Shell Script handelt, also sh oder bash. Der Inhalt sollte aber dem Vorschlag von Berlin_pi ein Python Script sein, also verwendet man üblicherweise als Dateiendung .py
    Der sudo Befehl kann in Python nicht in der Form ausgeführt werden - es handelt sich wie gesagt nicht um ein bash Script was du zuvor hattest sondern um ein Python Script => andere Syntax.
    Auch die letzte Zeile kann folglich nicht so da stehen...


    Ich bezweifel ehrlich gesagt auch das die 3.Zeile überhaupt irgend etwas killt, wenn du bei dem rm Befehl das -f weglässt erhälst du eine Fehlermeldung und das aus gutem Grund: Es handelt sich um ein Verzeichnis was nur mit dem Parameter "-r" gelöscht werden kann. Aber löschen willst du das Verzeichnis ja nicht weil sich darin die abzuspielende Datei befindet.... Ergo ist der Befehl gänzlich falsch. Das war schon mit dem "read a" in deinem Script aus Beitrag#1 so, was da so absolut kein Sinn macht und überflüssig ist.


    Ich glaub aber auch das der Vorschlag von Berlin_pi nicht wirklich etwas an deinem Problem ändert. Dein Text ließt sich halt schwer weil der wichtige Teil lieblos in einem klumpen Text da irgendwie hingeklatscht steht mit ellenlangen ( ) und etlichen Satzzeichen usw... Noch mal aufgebröselt:



    Also mal von dem Chaos des Textes abgesehen:


    HEUTE wird eine Präsentation mit Dateinamen "a.odp" abgespielt.
    HEUTE ABEND wird eine neue Präsentation mit Dateinamen "Vorlage.odp" via Samba auf den Pi Kopiert.
    MORGEN FRÜH soll der Pi neu starten und ab dann "Vorlage.odp" ausführen.


    Ist das soweit korrekt?

  • Stimmt, das ist sehr chaotisch, weil ich zu viele Dinge auf einmal mitteilen wollte, ich übernehme dein Prinzip mal, ist übersichtlicher:


    HEUTE wird eine Präsentation mit Dateinamen "a.odp" abgespielt.
    HEUTE ABEND wird eine neue Präsentation mit Dateinamen "1-7-2016.odp" via Samba auf den Pi Kopiert.
    MORGEN FRÜH soll der Pi neu starten oder ein Cronjob laufen und (ab) dann "1-7-2016.odp" ausführen.
    AM NÄCHSTEN ABEND wird eine neue Präsentation mit Dateinamen "2-7-2016.odp" via Samba auf den Pi Kopiert.
    AM NÄCHSTEN MORGEN soll der Pi neu starten oder ein Cronjob laufen und (ab) dann "2-7-2016.odp" ausführen.


    Danke für deine Geduld :)

  • Benenne die Dateien einfach nach dem Datum der Vorführung (01-07-2016.odp) und starte morgens deinen cronjob. Dort rufst du
    "soffice $(date +'%d-%m-%Y').odp" auf.

    Menschen die keine Ironie verstehen finde ich super!

    Edited once, last by llutz ().

  • Es ist eigentlich unnötig den Pi jedes mal zu rebooten. Das einzige was du machen musst ist das Programm zu beenden, zum Beispiel Abends um 21 Uhr. Morgens greift dann eine crontab und initiiert die Wiedergabe der Datei.


    Diesem Prinzip folgend könntest du sogar dein altes Script verwenden, weil die "ABEND"s hochgeladene Datei neuer ist.


    Also wie folgt:


    Crontab Eintrag:

    Code
    0 21 * * *    /usr/bin/killall -9 soffice >>/tmp/log.present 2>&1
    0 07 * * *    /bin/bash /home/pi/present.sh >>/tmp/log.present 2>&1


    present.sh

    Code
    cd /home/pi/Bildschirmausgabe
    ACTUAL=$(ls -t | head -1)
    mv -f $ACTUAL a.odp
    soffice -show a.odp


    Der erste Crontabeintrag killt alle Programme des Namens "soffice". Der wird um 21:00 Uhr ausgeführt.
    Der zweite Crontabeintrag führt dein Script (leicht abgewandelt) aus und spielt die aktuellste Datei ab, wobei die Datei zuvor in a.odp umbenannt wird. Der wird um 07:00 Uhr ausgeführt.


    Auf dieser Basis kannst du alles so lassen wie gehabt. Dein Mitarbeiter kann jeden Abend eine Datei "Vorlage.odp" hochladen, wie die Datei heißt ist egal. Am nächsten Morgen wird um 0700 die Datei in "a.odp" umbenannt und anschließend abgespielt oder was auch immer ;)


    Bezüglich Crontab siehe auch FAQ => Nützliche Links / Linksammlung => crontab

  • Servus,
    umbenennen würd' ich das nicht ... ich finde da den Vorschlag


    Benenne die Dateien einfach nach dem Datum der Vorführung ...


    besser.
    Zudem würde es in meinen Augen Sinn machen erst mal zu überprüfen, ob die Datei überhaupt exisitert. Kann ja mal vergessen worden sein. Mit anderen Worten: entweder Du speicherst eine Präsentation als Fallback mit einem speziellen Namen ab, die dann abgespielt wird, wenn keine aktuelle Datei verfügbar ist, oder Du merkst Dir den Namen der zuletzt abgespielten Datei und wiederholst diese.
    Bitte im Hinterkopf behalten, dass evtl. mehr als nur eine Datei fehlen kann.


    Das Ganze in einem bash-script, das dann die PID vom im Hintergrund gestarteten impress mit

    Code
    echo $! > /var/log/impress.pid


    oder so ähnlich speichern kann.
    Da kannst Du dann direkt einen kill drauf absetzen. Vielleicht mal probieren, ob ein einfacher kill `cat /var/log/impress.pid` ausreicht, oder ob die -9 notwendig ist. Bei -9 habe ich persönlich immer ein bisschen Bauchweh weil ich fürchte, dass da noch irgendwas im Speicher als Zombie hängen bleibt.
    Was Du jetzt genau starten musst ... und wie der kill letzendlich aussehen muss ... da würde ich mal auf der Kommandozeile herumexperimentieren.
    So gesehen würde ich dann die Vorschläge von meigrafd, bis eben auf die Umbenennung und den kill, als Anregung entsprechend abgewandelt übernehmen.
    Einen Zusatz evtl. noch: falls keine aktuelle Datei gefunden wurde, evtl. zwischendrin immer wieder mal prüfen, ob sie mittlerweile da ist.


    cheers,
    -ds-

  • Wenn a.odp die $ACTUAL Datei ist passiert nichts ;) Es käme ne Fehlermeldung aber die Datei bleibt wie sie ist. Der Fehler wird nach /tmp/log.present protokolliert.


    Dein Vorschlag die PID zu speichern und diese dann gezielt zu killen ist aber Oke :)
    Sähe dann so aus:


    Crontab Eintrag:

    Code
    0 21 * * *    /bin/kill -9 $(cat /var/run/pid.present) >>/tmp/log.present 2>&1
    0 07 * * *    /bin/bash /home/pi/present.sh >>/tmp/log.present 2>&1


    present.sh

    Code
    cd /home/pi/Bildschirmausgabe
    ACTUAL=$(ls -t | head -1)
    mv -f $ACTUAL a.odp
    soffice -show a.odp &
    echo $! > /var/run/pid.present
  • Einen hab' ich noch:
    daran denken, dass der RPi keine eingebaute Uhr hat ... also für den Zugriff auf einen Timeserver sorgen oder dem Pi eine RTC - bevorzugt eine DS3231 oder ähnlich genau - spendieren.
    (Näheres zur DS3231 bzw. warum keine DS1307 -> gibts hier <- oder -> oder auch hier <-).


    cu,
    -ds-

  • present.sh

    Code
    cd /home/pi/Bildschirmausgabe
    ACTUAL=$(ls -t | head -1)
    mv -f $ACTUAL a.odp
    soffice -show a.odp &
    echo $! > /var/run/pid.present


    Wozu das mv?

    present.sh

    Code
    cd /home/pi/Bildschirmausgabe
    ACTUAL=$(ls -t *.odp | head -1)
    soffice -show $ACTUAL &
    echo $! > /var/run/pid.present


    Und ja, das ACTUAL=... könnte auch noch weg :)

    Menschen die keine Ironie verstehen finde ich super!

    Edited once, last by llutz ().

  • Das "mv" dient dazu dass...
    a) das Verzeichnis nicht zugemüllt wird
    b) das Verzeichnis nicht aufgeräumt werden muss


    Läd der Mitarbeiter Heute Abend "Vorlage.odp" hoch wird die Datei Morgen Früh in a.odp umbenannt. Morgen Abend kann der Mitarbeiter dann wie gewohnt wieder "Vorlage.odp" hoch laden usw usw usw. Die Datei a.odp überschreiben kann er nicht da die ja zu der Zeit noch von soffice geöffnet ist.
    Würde man das nicht so machen müsste der Mitarbeiter immer eine andere Datei hochladen bzw anders benennen - ich kenn zwar den Mitarbeiter nicht aber Mir persönlich wäre es möglichst einfach angenehmer ;) Nennt mich faul aber die Datei immer "Vorlage.odp" zu benennen ist schon irgendwie bequem :fies: Naja, jedenfalls hab ich mir da scho was bei gedacht :D


  • Ich räume sowieso immer per cron/find auf, da fiele ein Verzeichnis mehr nicht auf.
    Aber gut, dass viele Wege nach Rom und manchmal auch zum Ziel führen. Wahlfreiheit.


    Ich wollte dir auch nicht unterstellen, dass du dabei nicht denkst :)

    Menschen die keine Ironie verstehen finde ich super!

  • Mein present.sh Script sieht derzeit so aus:
    (Jemand anders hat noch dran weitergearbeitet)


    Von Donnerstag auf Freitag hat die Präsentationsumstellung wohl geklappt und am Montag wurde sie von jemandem manuell gestartet und heute Morgen habe ich sie manuell gestartet.
    :@


    Cronjobs sehen so aus:


    0 21 * * * /bin/kill -9 $(cat /var/run/pid.present) >>/tmp/log.present 2>&1
    0 07 * * * /bin/bash /home/pi/present.sh >>/tmp/log.present 2>&1


    und dem present.sh habe ich noch das echo hinzugefügt:


    echo $! > /var/run/pid.present


    (ganz unten dran)

    Edited once, last by Pi-Tight ().

  • Neuer Stand:


    crontab:



    present.sh



    Habe die Arbeit von dem anderen Mitarbeiter auskommentiert, weil ich seine Arbeit nicht verwerfen wollte : )


    Ich berichte Morgen früh, ob es funktioniert hat! :danke_ATDE:

  • Hallo zusammen,


    um mal wieder zurück auf das Thema und die Aufgabenstellung zu kommen.


    Es soll die letzte = aktuellste Datei in einem Verzeichnis ermittelt werden und diese von einem Programm zur Anzeige gebracht werden.


    Code
    datei="$(ls -alct *.typ | head -n 1 | awk {'print $9'})"


    ermittelt die aktuellste Datei im aktuellen Verzeichnis


    Code
    datei="$(ls -alct /Pfad/zum/Verzeichnis/*.typ | head -n 1 | awk {'print $9'})"


    ermittelt die aktuellste Datei in einem Ziel-Verzeichnis.


    Die aktuellste Datei wird in der Variablen [font="Courier New"]datei[/font] gespeichert. Dass dies erfolgreich war, kann man durch

    Code
    echo $datei


    verifizieren.


    Dann braucht lediglich [font="Courier New"]$datei[/font] mit den entsprechenden Parametern von der Anwendung geöffnet / geladen / angezeigt zu werden. Beispielsweise

    Code
    cat $datei


    Statt [font="Courier New"]cat[/font] ist dann die Anwendung zur Anzeige von Präsentationen zu wählen.


    Und als Einzeiler diene der hier:

    Code
    soffice -show "$(ls -alct /Pfad/zum/Verzeichnis/*.typ | head -n 1 | awk {'print $9'})"


    womit die im benannten Verzeichnis aktuellste Präsentation zur Anzeige gelangen würde.


    Vorteil: Man kann die Datei mit beliebigem Namen erstellen, speichern und übertragen. Es wird immer die aktuellste Version angezeigt.
    Die ganze hier gepflegte Diskussion mit Umbenennen, Löschen etc. ist meiner Meinung nach Unfug und nicht zielführend - sondern manövriert mit großem Aufwand auf Nebenschauplätze, die dann auch erstaunlicherweise doch nicht zur Lösung führen.


    Beste Grüße


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Edited once, last by Andreas ().

  • Andreas: Du behandelst mit deinem langen Beitrag nur das ermitteln der aktuellen Datei - das ermitteln der aktuellen Datei war aber bereits geregelt:


    Code
    ACTUAL=$(ls -t | head -1)


    Aus der manpage von ls geht hervor:

    Code
    -t     sort by modification time, newest first


    -a ist hierfür nicht erforderlich da es keine "versteckte" Datei ist.
    -lc ist ebenfalls nicht erforderlich da die Details (Rechte, Größe, Besitzer, Zeit) nicht wichtig sind.


    Dein letzter Satz gilt also auch für Dich.



    Pi-Tight scheint leider nicht verstanden zu haben, worin der Unterschied zwischen einer pid Datei und dem ermitteln der PID via "ps", ist. Es macht keinen großen Unterschied wobei ich persönlich das manuelle Ermitteln via "ps" besser finde, denn das entspricht der Realität wohingegen die pid Datei nicht aktuell sein muss.


    Also das aktuelle Script sähe so aus:


    Es läuft also aktuell ein Prozess "soffice". Soweit so gut.


    Da das killen des soffice Prozesses bereits in dieses Script integriert ist benötigen wir auch nur einen Crontabeintrag:

    Code
    crontab -e

    Wichtig wäre hier ob der Desktop über den Benutzer "pi" oder einen anderen Benutzer läuft, oder ob soffice als Benutzer pi oder root ausgeführt wurde - denn der Benutzer pi darf nicht einen Prozess eines anderen Benutzers beenden.

    Code
    0 07 * * *    /bin/bash /home/pi/present.sh >>/tmp/log.present 2>&1

    Falls Fehler auftreten bitte die Logdatei /tmp/log.present prüfen (das hast du hier bisher nicht gepostet)


    Nun erstelle ich eine Datei xyz.odp im Verzeichnis /home/pi/Bildschirmausgabe/ und führe dann "present.sh" aus - wenn es Manuell nicht funktioniert kann Crontab auch nicht zaubern, man muss auch nicht so lange warten bis Crontab zuschlägt...


    Code
    pi@raspberrypi:~$ ./present.sh    
    pi@raspberrypi:~$


    Der erste Start scheint also funktioniert zu haben. Eine Überprüfung ergibt:

    Code
    pi@raspberrypi:~$ ps -ef | grep -v grep | grep soffice | awk {'print $2'}
    6260
    pi@raspberrypi:~$ ls -t Bildschirmausgabe/            
    aktuell.odp
    pi@raspberrypi:~$


    Sieht gut aus.


    Nun führe ich das Script erneut aus und tu so als sei es bereits morgen früh - aber es hat keiner eine Neue Datei hochgeladen:

    Code
    pi@raspberrypi:~$ ./present.sh    
    mv: ‘aktuell.odp’ and ‘aktuell.odp’ are the same file
    pi@raspberrypi:~$ ls -t Bildschirmausgabe/
    aktuell.odp
    pi@raspberrypi:~$ ps -ef | grep -v grep | grep soffice | awk {'print $2'}
    7190
    pi@raspberrypi:~$


    Die Fehlermeldung kann man ignorieren, es wurde ja keine neue Datei erstellt. Man sieht aber weiterhin das Vorhandensein einer aktuell.odp Datei und auch das nun "soffice" mit einer anderen PID läuft.


    Nun erstell ich eine neue Datei xyz.odp und führe das Script erneut aus:

    Code
    pi@raspberrypi:~$ touch Bildschirmausgabe/xyz.odp    
    pi@raspberrypi:~$ ls -t Bildschirmausgabe/                               
    xyz.odp  aktuell.odp
    pi@raspberrypi:~$ ./present.sh                                           
    pi@raspberrypi:~$ ps -ef | grep -v grep | grep soffice | awk {'print $2'}
    7877
    pi@raspberrypi:~$ ls -t Bildschirmausgabe/       
    aktuell.odp
    pi@raspberrypi:~$


    voilà , sieht doch super aus?! :-/ Also was gibts daran nun zu meckern @ Andreas?



    Bitte ersetze das Script und führe es manuell aus - falls es bei Dir nicht wie gewünscht funktioniert dann versuche bitte mehr Details zu geben wie zB Fehlermeldungen oder mehr Beschreibungen etc.