Zoner
Anmeldungsdatum: 30. August 2019
Beiträge: 121
|
Ich möchte mir einen Cronjob anlegen (erstmalig) und habe einige Fragen, die ich leider auf die schnelle nicht per Recherche beantwortet bekomme.
Bzw. hätte ich gerne Kommentare, zu Fehlern oder Verbesserungen meines Scripts, da es wol bei weitem nicht optimal sein wird. Hier als Beispiel mit youtube-dl Ich möchte als Beispiel einen Kanal auf Youtube alle 10 Minuten auf neue Videos überprüfen und falls es ein neues gibt, soll dies auf eine externe Festplatte geschrieben werden (auf die weiteren Funktionen von youtube-dl gehe ich erstmal nicht weiter ein). Ist also eine Menge Text mit vielen Sonderzeichen. | cd '/media/user/Festplattenname/VideoOrdner' && find abc123 || { touch abc123 && youtube-dl --restrict-filenames --yes-playlist --merge-output-format mp4 -if 'bestvideo[ext=mp4]+bestaudio[ext=m4a]' --limit-rate 25.3M --force-ipv4 --sleep-interval 2 --max-sleep-interval 12 -o '%(upload_date)s--%(title)s--%(id)s-%(height)sp%(fps)s_%(view_count)05dvs_%(duration)ss.%(ext)s' --add-metadata --embed-thumbnail --download-archive '/media/user/Festplattenname/VideoOrdner/archivliste.txt' 'https://www.youtube.com/c/irgendwessenaccount/videos' ; rm abc123 ; } ; exit
|
Das Script macht folgendes: Es wird erstmal der finale Speicherort geöffnet per "cd" von wo aus weiter gearbeitet wird.
Wenn das erfolgreich geschehen ist (die Festplatte also auch wirklich eingehangen ist), dann soll das eigenetliche Script ausgeführt werden (innerhalb der "{" Klammern). Da dieses Script (sollte es ein neues Video finden) aber unter umständen deutlich länger als 10 Minuten benötigt und ich nicht will, dass mehrere dieser Prozesse gestartet werden (weil alle 10 Minuten das Script nach neuen Videos suchen soll), prüfe ich zuvor, ob die Datei abc123 existiert und wenn nicht wird diese angelegt und dann das eigentliche Script gestartet. Ist sie aber vorhanden, ist das ein Zeichen, dass das Script bereits läuft und das neue Script wird dann angewiesen sich zu beenden (per exit). Das laufende Script hingegen löscht die Datei abc123 nach dem es vollständig durchgelaufen ist wieder (damit im nächsten 10 min Intervall sich ein neues starten kann) und beendet sich dann mit exit. So wird gewährleistet, dass das Script immer nur einmal gleichzeitig läuft. Jetzt möchte ich fragen ob das setzen der Klammer "}" das arbeiten mit "&&" und "||" richtig durchgeführt wurde, das doppelte exit am Ende notwendig ist...
Wenn ich den Code in der Shell ausführe, klappt soweit alles.
Ich hab im Internet auch die Benutzung der eckigen "[" Klammer gesehen (leider ohne dessen Funktion zu beschreiben) und wüsste gerne ob diese eine Funktion hat und welche? In der Wiki sind nur "(" und "{" beschrieben. Nun möchte ich das aber als Crontab alle par Minuten laufen lassen.
Ich habe mir dazu erstmal der Einfachheit halber den "Task Scheduler" (GUI) installiert. Der ist an sich selbsterklärend.
Nun habe ich dort unter "command" aber statt auf eine Bashdatei zu verweisen das Script original eingegeben. Mit "Run now" funktioniert dieses auch (Shell öffnet sich, alles läuft korrekt ab und schließt sich automatisch). Wenn ich aber einstelle, der Crontab soll testweise jede Minute durchgeführt werden, dann öffnen sich keine Fenster (was nach meiner Recherche wol normal ist, wenn man mit Cron arbeitet, was wol auch nervig wäre). Wie bekomme ich jetzt aber heraus ob der Cronjob läuft? Und kann man sich den irgendwie schick anzeigen lassen? (z.B. mit einem Icon, solange er läuft oder einer kleinen Infomeldung, sobald er startet). Und wie mache ich aus diesem Script eine Bashdatei? Soweit ich mich belesen habe, muss ich das Script komplett umwandeln? Statt mit "&&" und "||" mit "if" und "else" arbeiten?
Oder gibts da eine einfacherere Methode das umzukonvertieren ohne sich in Bashscript einzuarbeiten? (wofür ich aktuell nur sehr wenig Zeit habe)
Ich finde nur Beispiele wo die Befehle einfach nur aneinader gereit werden, z.B.: | #!bin/bash
cd bla/blub
find abc123
touch abc123
|
Aber dann habe ich ja keine Abhängigkeiten mehr ("&&", "||") etc...
|
fleet_street
Top-Wikiautor
Anmeldungsdatum: 30. August 2016
Beiträge: 2149
Wohnort: Hunsrück
|
Ich wage mich mal, den Anfang zu machen, damit hinterher es alle besser wissen. 😉 😀 Du musst (fast) gar nichts. Wenn du sonst nichts vorhast, reicht es aus, wenn in der ersten Zeile ein Shebang steht, also
#!/usr/bin/bash
s. a. Shell/Bash-Skripting-Guide für Anfänger Es ist zwar nicht schön, dass man deinen Wurm nicht sofort lesen kann, aber du hast ihn zusammengebaut und verstehst ihn vielleicht auch noch in zwei Jahren. Daher kann alles so wie es ist in die zweite Zeile. Zack, feddich! Wenn es doch ein wenig lesbarer werden soll, dann kannst du mit Zeilenumbrüchen arbeiten, sofern das in dem Wurm überhaupt geht. Dies wäre ein Backslash, auf den ohne Leerzeichen direkt der Zeilenumbruch kommen muss. Mit einem Backslash werden Dinge „maskiert“ – so der Fachausdruck –, damit sie vom Computer nicht interpretiert werden. In dem Fall wird der Zeilenumbruch maskiert, damit er nicht das eine eines Kommandos bewirkt. Und eine kleine Sache, ich hätte nicht find abc123 verwendet, da dies ggf. in die Unterverzeichnisse absteigt, was unnötig „lange“ dauern könnte. Mein Test sähe so aus:
[ ! -f abc123 ] Es gäbe noch andere Ansätze, z. B flock, aber du möchtest dich für den Anfang ja nicht einlesen. 😉
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Zwischen einem Script und einer Bashdatei bestehen eigentlich keine, bzw. nur subtile Unterschiede. Der von fleet_street erwähnte Shebang sollte aber benutzt werden, nur liegt das Programm bei mir nicht in /usr/bin sondern in /bin. Richtig ist, dass man das:
| cd '/media/user/Festplattenname/VideoOrdner' && find abc123 || { touch abc123 && youtube-dl --restrict-filenames --yes-playlist --merge-output-format mp4 -if 'bestvideo[ext=mp4]+bestaudio[ext=m4a]' --limit-rate 25.3M --force-ipv4 --sleep-interval 2 --max-sleep-interval 12 -o '%(upload_date)s--%(title)s--%(id)s-%(height)sp%(fps)s_%(view_count)05dvs_%(duration)ss.%(ext)s' --add-metadata --embed-thumbnail --download-archive '/media/user/Festplattenname/VideoOrdner/archivliste.txt' 'https://www.youtube.com/c/irgendwessenaccount/videos' ; rm abc123 ; } ; exit
|
nicht lesen kann. Räumen wir also auf! Zwischenfrage: Du sprichst von einem doppelten exit - ich sehe nur eins. Fehler? Exit am Ende des Scripts brauchst Du nicht. Wenn es ans Ende kommt, hört es von selbst auf. Stattdessen kannst Du mit
| cd Arbeitsverzeichnis
# Kommandos
cd -
|
arbeiten, um am Ende zurückzuspringen, aber wenn das Script da eh zuende ist, erübrigt sich auch das. Das Script ändert nicht das Arbeitsverzeichnis dessen, der es aufruft (außer er sourced es, aber das wäre ein extra Thema und ist nicht zu erwarten).
| cd Arbeitsverzeichnis
find abc123
|
Das sucht nicht nach einer Datei namens abc123, sondern sucht IN abc123. Wenn ein Verzeichnis abc123 existiert wird dieses und alle Unterverzeichnisse durchsucht. Ein Verzeichnis ist zwar auch eine Datei, und man kann so prüfen, ob die Datei existiert, aber auch hier weist fleet_street den richtigen Weg. Es gibt ein Programm test , das äquivalent ist zu dem Programm [ - der Verständlichkeit würde ich hier test vorschlagen (man test , help test ). Der Befehlt test -f DATEI prüft, ob die Datei existiert und eine konventionelle Datei ist (kein Verzeichnnis, Symlink, named Pipe ...) . Du benutzt sie als Lock, so nennt man das, also solltest Du sie auch so nennen. Eventuell willst Du dotlockfile benutzen, aber eine Datei youtube-dl.lck o.ä. im Verzeichnis /tmp dürfte alle Bedürfnisse erfüllen. Beim Restart des Computers etwa gelöscht zu werden.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | #!/bin/bash
VERZ='/media/user/Festplattenname/VideoOrdner'
LOCK=/tmp/ytdl.lck
download () {
youtube-dl --restrict-filenames --yes-playlist --merge-output-format mp4 -if 'bestvideo[ext=mp4]+bestaudio[ext=m4a]' --limit-rate 25.3M --force-ipv4 --sleep-interval 2 --max-sleep-interval 12 -o '%(upload_date)s--%(title)s--%(id)s-%(height)sp%(fps)s_%(view_count)05dvs_%(duration)ss.%(ext)s' --add-metadata --embed-thumbnail --download-archive "$VERZ/archivliste.txt" 'https://www.youtube.com/c/irgendwessenaccount/videos'
}
cd $VERZ
test -f $LOCK || {
touch $LOCK && download
rm $LOCK
}
|
Zum Test kann man eine Funktion download so schreiben:
| download () { echo "download mock" }
|
dann muss man nicht dauernd was downloaden, um das Hauptprogramm zu testen, das jetzt in seiner Struktur erkennbarer ist.
Ein zweiter Vorteil ist schon angerissen: Man hat 2 Teile, die man unabhängig voneinander testen kann. In der Downloadfunktion habe ich --download-archive "$VERZ/archivliste.txt" verwendet. Nachdem wir das Lockfile nach /tmp schreiben (was bedeutet, dass 2 unterschiedliche User nicht das gleiche Script nutzen können, ohne sich ins Gehege kommen zu können) und ich sonst nirgends das aktuelle Verzeichnis am Werk sehe (Speicherort für mp4-Dateien mit Defaultnamen?) kann man das cd $VERZ eigentlich auch rauswerfen. Bestimmt hat youtube-dl eine Option, den Speicherort auch als Parameter zu spezifizieren. Die Downloadfunktion kannst Du wie von fleet_street so aufräumen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | download () {
youtube-dl --restrict-filenames \
--yes-playlist \
--merge-output-format mp4 \
-if 'bestvideo[ext=mp4]+bestaudio[ext=m4a]' \
--limit-rate 25.3M \
--force-ipv4 \
--sleep-interval 2 \
--max-sleep-interval 12 \
-o '%(upload_date)s--%(title)s--%(id)s-%(height)sp%(fps)s_%(view_count)05dvs_%(duration)ss.%(ext)s' \
--add-metadata \
--embed-thumbnail \
--download-archive "$VERZ/archivliste.txt" \
'https://www.youtube.com/c/irgendwessenaccount/videos'
}
|
Wichtig: Nach dem Backslash darf kein Zeichen mehr kommen, auch kein Leerzeichen, nur der Zeilenumbruch.
|
fleet_street
Top-Wikiautor
Anmeldungsdatum: 30. August 2016
Beiträge: 2149
Wohnort: Hunsrück
|
user_unknown schrieb: … nur liegt das Programm bei mir nicht in /usr/bin sondern in /bin.
Bei mir schon (Wo liegt bash? /usr/bin oder /bin ?), aber das ist nicht überall der Fall. Also ist /bin/bash besser. 👍
|
Zoner
(Themenstarter)
Anmeldungsdatum: 30. August 2019
Beiträge: 121
|
user_unknown schrieb: Zwischenfrage: Du sprichst von einem doppelten exit - ich sehe nur eins. Fehler? Exit am Ende des Scripts brauchst Du nicht. Wenn es ans Ende kommt, hört es von selbst auf.
Das "doppelte Exit" hatte ich während des Text Verfassens schon behoben, ohne den Text zu ändern. War leider mein Fehler.
Sah quasi so aus:
| ...endwessenaccount/videos' ; rm abc123 ; exit ; } ; exit
|
Das letzte Exit behandelt er wegen ";" aber so oder so,
oder ich hatte
im Code stehen, ich weiß es nicht mehr. Hab das erste mal mit diesen Zeichen gearbeitet und die Logik hat sich mir auf die Schnelle erst nach und nach erschlossen (viele saubere und unsauberere Wege führen nach Rom). Zwischenzeitlich habe ich einfach folgendes in die Konsole eingegeben, was quasi das selbe bewirkt aber nicht so elegant ist, wie ein Cronjob aber in der bloßen Konsole funktioniert (nur der Anfang und das Ende sind zu beachten): | while true ; do cd '/media/user/Festplattenname/VideoOrdner' && find abc123 || { touch abc123 && youtube-dl --restrict-filenames --yes-playlist --dateafter 20201121 --playlist-end 3 --merge-output-format mp4 -if 'bestvideo[ext=mp4]+bestaudio[ext=m4a]' --limit-rate 25.3M --force-ipv4 --sleep-interval 2 --max-sleep-interval 12 -o '%(upload_date)s--%(title)s--%(id)s-%(height)sp%(fps)s_%(view_count)05dvs_%(duration)ss.%(ext)s' --add-metadata --embed-thumbnail --download-archive '/media/user/Festplattenname/VideoOrdner/archivliste.txt' 'https://www.youtube.com/c/irgendwessenaccount/videos' ; rm abc123 ; } ; date +"%T"; sleep 1800 ; done
|
(das "date" am Ende dient der Kontrolle, wann das Script zuletzt ausgeführt wurde, bzw. dass es nicht hängen geblieben ist) Das mit dem "Wurm" ist wirklich nicht sehr elegant und normalerweise schreibe ich deutlich saubereren Code (zumindest vor Jahrzehnten als ich mit MSDos Batch Dateien geschrieben und dafür sogar extra Farbtabellen angelegt habe, für schicke, bunte, animierte Ausgaben...) aber bisher arbeitete ich nur pur mit Konsole, da gehts ja nicht anders (und stört mich bisher nicht). Und in Youtube-Dl kann man auch Configfiles anlegen, um nicht immer diesen riesen Text eintippen zu müssen. Aber den kopiere ich mir lieber aus meinen Textdateien oder hole den in der Konsole mit den Pfeiltasten hervor, weil ich sowieso ständig die Optionen individuell anpasse und haufenweise Configfiles anlegen müsste. Da arbeite ich dann lieber mit dem Wurm oder besser mit Bashdateien, mit denen ich mich bisher aber nicht asukannte. Das mit dem Backslash ist ein guter Hinweis! Ich habe mich auch schon gewundert, dass die Konsole manchmal, wenn ich Code unsauber kopiert habe, er diesen sofort gestartet hat weil dort ein Zeilenumbruch mitkopiert wurde (hab ich also schon selbst beobachtet). Dass das mit der "abc123" Dateisuche eine unsaubere Lösung ist, hab ich mir schon gedacht, mir fiel in dem Moment nichts besseres ein. Hab wo gelesen (glaub auf stackexchange.com), dass man einem Cronjob auch eine PID vergeben und diese darauf Prüfen kann, um zu prüfen ob der Prozess bereits läuft. Das wurde als sauberste Lösung angepriesen, ich hab den Code dafür aber nicht auf Anhieb verstanden (mich generell mit der PID Geschihcte noch nicht auseinander gesetzt) und es erstmal dabei belassen. (normalerweise eigne ich mir das Wissen immer sofort an aber Coronabedeingt hab ich derzeit einfach unglaublich viel zu tun und eigentlich nicht mal hierfür Zeit aber es hilft als Ablenkung einwenig dem Wahnsinn zu entkommen)
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Zoner schrieb: Das mit dem "Wurm" ist wirklich nicht sehr elegant und normalerweise schreibe ich deutlich saubereren Code (zumindest vor Jahrzehnten als ich mit MSDos Batch Dateien geschrieben und dafür sogar extra Farbtabellen angelegt habe, für schicke, bunte, animierte Ausgaben...) aber bisher arbeitete ich nur pur mit Konsole, da gehts ja nicht anders (und stört mich bisher nicht).
Sag sowas nicht!
Aber das mit dem Backslash ist ein guter Hinweis! Ich habe mich auch schon gewundert, dass die Konsole manchmal, wenn ich Code unsauber kopiert habe, er diesen sofort gestartet hat weil dort ein Zeilenumbruch mitkopiert wurde (hab ich also schon selbst beobachtet). Dass das mit der "abc123" Dateisuche eine unsaubere Lösung ist, hab ich mir schon gedacht, mir fiel in dem Moment nichts besseres ein. Hab wo gelesen (glaub auf stackexchange.com), dass man einem Cronjob auch eine PID vergeben und diese darauf Prüfen kann, um zu prüfen ob der Prozess bereits läuft. Das wurde als sauberste Lösung angepriesen, ich hab den Code dafür aber nicht auf Anhieb verstanden (mich generell mit der PID Geschihcte noch nicht auseinander gesetzt) und es erstmal dabei belassen. (normalerweise eigne ich mir das Wissen immer sofort an aber Coronabedeingt hab ich derzeit einfach unglaublich viel zu tun und eigentlich nicht mal hierfür Zeit aber es hilft als Ablenkung einwenig dem Wahnsinn zu entkommen)
Gibt Dir alle PIDs laufender Prozesse mit dem Namen bash aus.
die PID des aktuellen Prozesses in einem Bashscript. Ich würde Lockfile und PID für gleich gut halten und das System verwendet auch beides.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12834
|
Zoner schrieb:
Dass das mit der "abc123" Dateisuche eine unsaubere Lösung ist, hab ich mir schon gedacht, mir fiel in dem Moment nichts besseres ein. Hab wo gelesen (glaub auf stackexchange.com), dass man einem Cronjob auch eine PID vergeben und diese darauf Prüfen kann, um zu prüfen ob der Prozess bereits läuft.
Wenn Du das mit Systemd Timer statt Cron machst, kann dir Systemd das auch abnehmen und dafür sorgen, dass ein Dienst nur ein Mal gestartet wird. ich glaube, das ist sogar das Standardverhalten.
|
Zoner
(Themenstarter)
Anmeldungsdatum: 30. August 2019
Beiträge: 121
|
Bei mir liegt bash in /usr/bin und /bin. Ich habe noch 2 oder 3 Probleme: Wenn ich im Task Scheduler die .sh Datei angebe, dann funkioniert "Run Now" aber ansonsten wird der Job nicht ausgeführt.
Zweites Problem ist, es öffnet sich (zumindest bei "Run Now") ein Fenster, was ja eigentlich nicht der Fall sein sollte? Oder benötige ich noch eine Art "echo off" Befehl dafür in meinem Script? (oder es ist bei "Run Now" einfach Absicht)
Drittes Problem, das Fenster schließt sich nicht mehr. Es kommt nur eine Aufforderung, dass ich dies selbst bewerkstelligen soll. Wenn ich das aber tue (mit CTRL-C z.b.), dann kommt nur die Fehlermeldung
| Warning: Program 'bash' crashed.
|
Wenn ich die Bashdatei direkt anklicke und ausführe funktioniert sie aber einwandfrei. (es erscheint auch kein Fenster, die Lockdatei wird aber angelegt und der Zeitraum wie lange sie existiert ist plausibel) unter "crontab -e" sieht auch alles vernünftig aus. Habe 45 * * * * (aktuelle Uhrzeit + eine Minute) und */2 * * * * ausprobiert, bzw. * * * * *. Es passiert aber nichts. Ansonsten bedanke ich mich aber bis hierher für die detailierte Hilfe!
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12834
|
Bei Systemd brauchst Du zwei Units: einen Service und einen Timer, typischweise mit dem selben Namen und nur einer anderen Endung. Du müsstest die mal posten, damit Dir an der Stelle weiter geholfen werden kann.
|
Zoner
(Themenstarter)
Anmeldungsdatum: 30. August 2019
Beiträge: 121
|
Habe mich jetzt mal in Systemd eingelesen. Das gefällt mir glaub ich tatsächlich besser.
Zumindest funktioniert es. Wobei mich dennoch interessieren würde warum der Crontab nicht funktioniert. Hab es so gemacht: bla.service
| [Unit]
Description=blageblubber
[Service]
ExecStart=/user/pfadzurbash/bash
|
(habe irgendwo gelesen dass es besser/stabiler ist, wenn man das ".sh" weglässt, weil der Punkt in manchen Programmen als Befehl interpretiert wird. Sollte ich es so beibehalten?) bla.timer
| [Unit]
Description=blageblubber
[Timer]
OnBootSec=10m
OnUnitInactiveSec=30m
RandomizedDelaySec=1m
|
abgelegt unter /etc/systemd/system per sudo touch und sudo nano. ("Persistent=true" macht glaube ich nur Sinn für feste Uhrzeiten/Termine ?) Gestartet mit
| systemctl start bla.timer
|
Jetzt habe ich einige Fragen:
wenn ich den Timer starte, muss ich mein Userpasswort eingeben. Wenn der Rechner bootet, startet der Timer aber trotzdem im Hintergrund? Oder hätte ich den woanders ohne Sudo erstellen sollen? Wie funktioniert "RandomizedDelaySec" genau? Wird diese Zeit zur vorgegebenen beaufschlagt oder kann das auch bedeuten, dass der Dienst um diese Zeit früher gestartet werden könnte? (hab ich nur zum Test drinnen) Wenn ich
| systemctl status bla.timer
|
eingebe, was bedeuten die farbigen Punkte hinter "Triggers"? Meist ist der Grau. Manchmal aber auch grün oder rot.
Grau bedeutet wol "Standby", Grün "Service läuft gerade" und was bedeutet rot?
Zusammen mit "RandomizedDelaySec" hatte ich oft den roten Punkt gesehen, ohne nicht so oft (gefühlt). Auch ist die Ausführung zeitentechnisch sehr ungenau (ohne "RandomizedDelaySec").
Wenn ich den Status prüfe, dann führt er den Dienst sofort aus, wenn die vorgebene Zeit erreicht wurde. Kontrolliere ich den Status aber nicht ständig, dann braucht der Dienst länger, bis zur nächsten Ausführung, obwohl eine Minute eingestellt ist. Warum eigentlich überhaupt diese eine Minute generelle Ungenauigkeit (also wenn man eine Minute einstellt, dass es auch mal bis zu 2 Minuten dauern kann)? Dient das der Entlastung des Systems oder was ist der Hintergrund? Hatte Cronjob meine ich auch. (wobei es bei Systemd die Möglichkeit gibt, auch Sekundengenau zu arbeiten)
Ich brauche das bisher zwar eher höchstens halbstündlich aber ich kann mir Szenarien vorstellen, wo ich etwas Sekundengenau ausgeführt haben wollte. (wobei man das evtl. aber auch per Script selbst machen könnte, Systemd startet das Script eine Minute vorher und das Script prüft nochmal die Zeit und arbeitet dann Sekundengenau als Beispiel...) Find ich nur komisch dass solche Zeit relevanten Dienste nur Minuten genau arbeiten. Aber vielleicht hab ich da nur was nicht ganz verstanden. Nochwas:
Kann ich auch sauber mehrere Scripte starten?
| [Unit]
Description=blageblubber
[Service]
ExecStart=/user/pfadzurbash/bash1
ExecStart=/user/pfadzurbash/bash2
ExecStart=/user/pfadzurbash/bash3
|
Und werden diese dann hintereinander ausgeführt oder alle gleichzeitig? Oder sollte man sowas lieber mit getrennten Services handhaben? (oder schlichtweg anderer Syntax in der .service)
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Zoner schrieb: Habe mich jetzt mal in Systemd eingelesen. Das gefällt mir glaub ich tatsächlich besser.
Da will ich Dich nicht von abbringen.
Zumindest funktioniert es. Wobei mich dennoch interessieren würde warum der Crontab nicht funktioniert.
Crontab - chronologisch, chronometer - der erste Teil steht für Zeit, tab steht für Tabelle. Es ist also wenn, dann DIE Crontab, die nicht funktioniert, bzw. ein Eintrag in dieser. Was heißt "nicht funktioniert"? Ich habe gescrollt und keine Crontabzeile gesehen, die man lesen könnte. Eine Kristallkugel habe ich nicht.
Gibt es Fehlermeldungen? Bitte mit Cut-n-paste. Fehlermeldungen findest Du in den Logfiles.
Hab es so gemacht: bla.service
| [Unit]
Description=blageblubber
[Service]
ExecStart=/user/pfadzurbash/bash
|
(habe irgendwo gelesen dass es besser/stabiler ist, wenn man das ".sh" weglässt, weil der Punkt in manchen Programmen als Befehl interpretiert wird. Sollte ich es so beibehalten?)
Welches .sh? Ich seh' keins. Niemand kann verhindern, dass jemand morgen ein Programm schreibt, das einen Punkt als Programm interpretiert, aber mir kommt das doch sehr, sehr fragwürdig vor. Die Aussage ist aber auch zu unklar, um jetzt zu rätseln. Auf mich wirkt es wie BS. Vielleicht ein Mißverständnis. Dateiendungen weglassen ist eine Windowsunsitte.
Jetzt habe ich einige Fragen:
wenn ich den Timer starte, muss ich mein Userpasswort eingeben. Wenn der Rechner bootet, startet der Timer aber trotzdem im Hintergrund? Oder hätte ich den woanders ohne Sudo erstellen sollen?
Ein richtig eingerichteter Systemd-Dienst sollte Dich nicht nach einem Passwort fragen - der Sinn der Dienste ist ja, dass sie ohne Benutzereingriff laufen.
Wenn ich
| systemctl status bla.timer
|
eingebe, was bedeuten die farbigen Punkte hinter "Triggers"? Meist ist der Grau. Manchmal aber auch grün oder rot.
Grau bedeutet wol "Standby", Grün "Service läuft gerade" und was bedeutet rot?
Zusammen mit "RandomizedDelaySec" hatte ich oft den roten Punkt gesehen, ohne nicht so oft (gefühlt).
Der weltbekannte Manualaufruf lautet man systemctl und sagt: Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output error (5)
The dot ("●") uses color on supported terminals to summarize the unit state at a glance. White indicates
an "inactive" or "deactivating" state. Red indicates a "failed" or "error" state and green indicates an
"active", "reloading" or "activating" state.
Nochwas:
Kann ich auch sauber mehrere Scripte starten?
| [Unit]
Description=blageblubber
[Service]
ExecStart=/user/pfadzurbash/bash1
ExecStart=/user/pfadzurbash/bash2
ExecStart=/user/pfadzurbash/bash3
|
Was hindert Dich es auszuprobieren und zu berichten?
Und werden diese dann hintereinander ausgeführt oder alle gleichzeitig? Oder sollte man sowas lieber mit getrennten Services handhaben? (oder schlichtweg anderer Syntax in der .service)
|
Zoner
(Themenstarter)
Anmeldungsdatum: 30. August 2019
Beiträge: 121
|
Irgendwie spinnt systemd in letzter Zeit bei mir und ich weiß nicht warum.
Ich habe verschiedene Timer/Services angelegt und alles funktionierte eigentlich Wochenlang einwandfrei. Ich hab aber neuerdings merkwürdige Phänomene: In einem Ordner habe ich 3 fast identische Bash Dateien. Diese haben auch unterschiedliche Namen.
Bash1 wird von systemd regelmäßig gestartet. Dann gibt es noch Bash2 und 3 zum manuellen starten aber leicht geändertem Code.
Wenn ich jetzt in Bash2 Veränderungen vornehme und dann auf "run in Konsole" klicke, führt er Bash1 aus.
Hab dann eine neue Datei angelegt, einen anderen Namen gegeben, den Code hinein kopiert (der sich leicht von Bash1 unterscheidet), wieder "run in Konsole" und er führt wieder den Code aus Bash1 aus.
Als ob er immer die "erste" Datei im Ordner startet, egal welche Datei ich anklicke... In anderen Ordnern mit unterschiedlichen Bashdateien führt er aber die aus, die ich anklicke... Ebend gerade ist mir (in einem anderen Fall) aufgefallen, das eine andere Bashdatei ständig jede Minute ausgeführt wird, obwohl diese nur halbstündlich jeden Tag zwischen 12 und 23 Uhr ausgeführt werden soll.
Ich hab den Timer gestoppt und neu gestartet. Wenn er gestoppt ist, läuft das Script dennoch jede Minute. Unter Status steht auch, dass es gestoppt wurde. Und nach dem starten, dass die nächste Ausführung (wie es auch sein sollte) erst in 8h durchgeführt wird. Aber dennoch startet es jede Minute. Ich habe tatsächlich ein anderes Bashscript in einem anderen Ordner mit anderem Namen per systemd timer genau so eingestellt, dass dieses jede Minute ausgeführt wird, was auch korrekt durchgeführt wird. Aber ich habe sämtliche Namen, Pfade, Bezeichnungen und Timereinstellungen in systemd überprüft und diese sind alle korrekt und dennoch habe ich diesen Fehler. Ist es möglich das aus irgendeinem Grund verschiedene Bashscripte miteinader verknüft wurden? Unter /etc/systemd/system sind diese aber alle klar voneinander getrennt. Für jedes Script hab ich einen eigenen Service/Timer angelegt.
Weiß jemand was da los ist? Oder gibt es noch einen anderen Dienst oder einen weiteren Ordner mit Timern von dem systemd aus die Scripte startet?
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Ohne, dass wir selbst alles überprüfen können, ist dazu wenig zu sagen - außer bei uns wäre schon Änhnliches passiert. Sind die Scripte so kurz, dass Du sie hier in Codeblöcken wiedergeben könntest? Ich bin noch nicht firm mit dem systemd-timer - was zeigt denn:
| ls -l /etc/systemd/system/timers.target.wants/
|
|
Zoner
(Themenstarter)
Anmeldungsdatum: 30. August 2019
Beiträge: 121
|
$ ls -l /etc/systemd/system/timers.target.wants/ gibt das aus: total 0
lrwxrwxrwx 1 root root 33 Oct 8 10:44 anacron.timer -> /lib/systemd/system/anacron.timer
lrwxrwxrwx 1 root root 35 Oct 8 10:44 apt-daily.timer -> /lib/systemd/system/apt-daily.timer
lrwxrwxrwx 1 root root 43 Oct 8 10:44 apt-daily-upgrade.timer -> /lib/systemd/system/apt-daily-upgrade.timer
lrwxrwxrwx 1 root root 37 Oct 8 10:44 e2scrub_all.timer -> /lib/systemd/system/e2scrub_all.timer
lrwxrwxrwx 1 root root 32 Oct 8 10:44 fstrim.timer -> /lib/systemd/system/fstrim.timer
lrwxrwxrwx 1 root root 39 Oct 8 10:44 fwupd-refresh.timer -> /lib/systemd/system/fwupd-refresh.timer
lrwxrwxrwx 1 root root 35 Oct 8 10:44 logrotate.timer -> /lib/systemd/system/logrotate.timer
lrwxrwxrwx 1 root root 32 Oct 8 10:44 man-db.timer -> /lib/systemd/system/man-db.timer
lrwxrwxrwx 1 root root 35 Oct 8 10:44 motd-news.timer -> /lib/systemd/system/motd-news.timer
lrwxrwxrwx 1 root root 43 Oct 8 10:44 snapd.snap-repair.timer -> /lib/systemd/system/snapd.snap-repair.timer Und das eigentliche Setting sieht so aus: Im Ordner "/home/usr/Videos/youdl2" liegt die "bash2" 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | #!/bin/bash
YTBLINK='https://www.youtube.com/c/irgendeinkanal/videos'
VERZ='/home/usr/Videos/youdl2'
LOCK="$VERZ/bash2.lck"
download () {
youtube-dl --restrict-filenames \
--yes-playlist \
--merge-output-format mp4 \
-if 'bestvideo[ext=mp4]+bestaudio[ext=m4a]' \
--dateafter 20210101 \
--playlist-end 5 \
--limit-rate 25.3M \
--force-ipv4 \
--sleep-interval 2 \
--max-sleep-interval 12 \
-o '%(upload_date)s--%(title)s--%(id)s-%(height)sp%(fps)s_%(view_count)05dvs_%(duration)ss.%(ext)s' \
--add-metadata \
--embed-thumbnail \
--download-archive "$VERZ/list2.txt" \
$YTBLINK
}
cd $VERZ
test -f $LOCK || {
touch $LOCK && download
rm $LOCK && echo "$(tput bold)$(tput blink)$(tput setaf 2)█████$(tput sgr 0)$(tput bold)$(tput setaf 2) FINISH $(tput blink)█████$(tput sgr 0)"
}
|
An dem Script bastel ich noch (echo dient mir nur, wenn ich das Script manchmal manuell ausführe). Das Script hat meiner Meinung nach aber nichts mit dem Fehler zu tun, da die Ausführzeiten ja von systemd gesteuert werden. Und die Systemd Dateien: /etc/systemd/system/bash2.timer:
| [Unit]
Description=ytkanal2
[Timer]
OnCalendar=*-*-* 11..23:00,30:00
RandomizedDelaySec=20m
Persistent=true
|
/etc/systemd/system/bash2.service
| [Unit]
Description=ytkanal2
[Service]
ExecStart=/home/usr/Videos/youdl2/bash2
|
Das andere Script (bash1), dass sich auch in einem anderen Ordner befindet, das tatsächlich knapp jede Minute ausgeführt werden soll, ist exakt das gleiche (nur mit leicht anderem Verzeichniss, Youtubelink, und Dateinamen),
allerdings sehen dort die Einstellungen in systemd so aus: /etc/systemd/system/bash1.timer:
| [Unit]
Description=ytkanal1
[Timer]
OnBootSec=10m
OnUnitInactiveSec=1m
RandomizedDelaySec=1m
|
/etc/systemd/system/bash1.service:
| [Unit]
Description=ytkanal1
[Service]
ExecStart=/home/usr/Videos/youdl1/bash1
|
Nun ist es eben so, dass bash2 genauso oft gestartet wird wie bash1, obwohl in bash2 der Timer ganz anders gesetzt ist. Aber jedes Script sitzt in einem eigenen Ordner und auch sämtliche Bezeichnungen sind unterschiedlich (auch schon von Anfang an). Daher weiß ich nicht mehr, wo ich jetzt noch den Fehler suchen soll. Vielleicht ist es auch nur Zufall, das bash2 ebenfalls jeden Minute ausgeführt wird und hat mit den Einstellungen von bash1 nichts zu tun. Wenn ich
$ systemctl status bash2.timer
eingebe, kommt:
● bash2.timer -
Loaded: loaded (/etc/systemd/system/bash2.timer; static; vendor preset: enabled)
Active: inactive (dead)
Trigger: n/a
Triggers: ● bash2.service
Feb 04 11:57:49 R8 systemd[1]: Started ytkanal2.
Feb 04 12:01:22 R8 systemd[1]: bash2.timer: Succeeded.
Feb 04 12:01:22 R8 systemd[1]: Stopped ytkanal2.
Aber dennoch läuft das Script jede Minute
Starte ich es ($ sudo systemctl start bash2.timer), steht dort
● bash2.timer - ytkanal2
Loaded: loaded (/etc/systemd/system/bash2.timer; static; vendor preset: enabled)
Active: active (waiting) since Mon 2021-02-08 10:06:15 CET; 1s ago
Trigger: Mon 2021-02-08 11:06:01 CET; 59min left
Triggers: ● bash2.service
Feb 08 10:06:15 R8 systemd[1]: Started ytkanal2.
Also nächster Start in knapp einer Stunde. Dennoch wird das Script jede Minute ausgeführt. Das Script läuft nur dann nicht, wenn ich den Rechner neustarte. Sobald ich es einmal starte, läuft es wieder jede Minute durch, egal was ich anschließend mache. (timer stoppen, ändern, "restart" oder "$ sudo systemctl daemon-reload")
Alle anderen Timer/Scripte (bash1, bash3, bash4, alle mit unterschiedlichen Timer Einstellungen) arbeiten zu den Zeiten wie sie sollen und lassen sich auch stoppen. Ich habe nachdem das Script (bash2) schon lange korrekt lief, irgendwann Änderungen (am Script) vorgenommen und getestet, ohne aber den Namen der Datei oder die Einstellungen in systemd zu verändern. Etwa seit dem Zeitraum besteht dieses Problem (denn vorher startete bash2 auch zu den Zeiten wie es sollte). An den anderen Scripten habe ich aber auch Änderungen vorgenommen (ebenfalls ohne Änderungen in systemd) und diese starten immernoch zu Zeiten wie sie sollen und lassen sich stoppen. Das bash2 selbst arbeitet wie es soll, nur soll es eben nicht jede Minute ausgeführt werden, sondern so, wie es in der Timer Datei unter systemd steht. Ich verstehe eben nicht, warum das aufeinmal und nur bei diesem Script nicht mehr der Fall ist und warum ich es nicht ändern kann... Meine aktuelle Lösung besteht darin, dass ich die .lck Datei manuell anlege, damit das Script nicht mehr ausgeführt wird und ich dieses dann manuell vornehme. Denn aktuell bekomme ich diesen Prozess nicht anders gestoppt. Mir ist das ganze auch nur durch Zufall aufgefallen, weil die .lck Dateien (absichtlich zur Diagnose) direkt in den entsprechenden Downloadordnern angelegt werden (wo auch die Scripte liegen). Ich werde die Scripte, wenn ich Zeit finde, auch so abändern, dass eine zusätzliche Textdatei angelegt wird, wo die letzten hundert Ausführungen mit Zeitstempel protokolliert werden. Ich könnte jetzt den Timer und Service löschen, einen neuen Ordner/Script unter anderem Namen anlegen. Aber dann werde ich wol nicht mehr heraus finden, wo das Problem lag und der fehlerhafte Prozess geistert dann vermutlich auf ewig noch im System herum... Es wäre sinnig herauszufinden, was da auf das Script zugreift (ob das wirklich systemd ist oder welcher Teil davon, denn der eigentliche bash2.timer scheint ja ignoriert zu werden)
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Mit
ermittelst Du, welche Aufrufkette Dein Skript bash2 gestartet hät, während es läuft.
|