ubuntuusers.de

Shellscript, yt-dlp und crontab?

Status: Ungelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

thom_raindog

Avatar von thom_raindog

Anmeldungsdatum:
20. Mai 2005

Beiträge: 2848

Salue zusammen,

ich bin grade echt verwirrt. Ich hab n kleines Skript zusammengehackt, das per yt-dlp nach neuen Episoden in einer Playlist sucht, und diese bei Bedarf runterlädt. Klappt auch einwandfrei - WENN ich es händisch ausführe. Der Eintrag in die crontab als @daily läuft zwar, daber geht aber was schief.

Hier zunächst das Skript (bitte nur leise auslachen, danke).

 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/bash

#for debugging
set -xv

BASEPATH="/home/ICH/bin"
cd $BASEPATH
PLAYLIST="https://www.youtube.com/watch?v=P8pLvV3FjPc&list=PL1tiwbzkOjQydg3QOkBLG9OYqWJ0dwlxF"
CURRENT=$(<NOofEpisodes)
declare -i DIFFERENCE=0
TARGETPATH="/Pfad/Zu/Mediaserver"

echo $(date -u) "Last count of episodes: $CURRENT" >> log.file 2>&1

echo $(date -u) "Downloading Critical Role Campaign 3 Playlist as json and saving it as cr3.json" >> log.file 2>&1

yt-dlp --flat-playlist --print-json "$PLAYLIST" > cr3.json

#using jq to read cr3.json and output number of episodes.

NEW=$(jq -s length cr3.json)

echo $(date -u) "New count of episodes: $NEW" >> log.file 2>&1

#Calculate $DIFFERENCE. If >0 download as many episodes from playlist
#Substrace NEW from CURRENT; double brackets to transform strings to integers
((DIFFERENCE=$NEW-$CURRENT))
echo $(date -u) "Difference is: $DIFFERENCE" >> log.file 2>&1
#IF DIFFERENCE is >0 start downloading from episode $CURRENT to episode $NEW

if [ $DIFFERENCE -gt 0 ]
then
	echo $(date -u) "There is at least 1 new episode of CR 3. Starting download!" >> log.file 2>&1
	((START=$CURRENT+1))
	yt-dlp -f 22 --playlist-start $START --playlist-end $NEW -P "$TARGETPATH" $PLAYLIST
else
	echo -e $(date -u) "There are no new episodes. \n*sad smiley* \nIs it THURSDAY yet?" >> log.file 2>&1

fi
 
##Writing current episode number to NOofEpisodes
echo $(date -u) "New episode count now: $NEW"  >> log.file 2>&1
echo $NEW > NOofEpisodes

#end debugging
set +xv

Und händisch ausgeführt klappt das auch. Das JSON wird heruntergeladen, durch jq gejagt, die Zahl der items ausgelesen, schön mit der Zahl in NOofEpisodes verglichen, hübsch geloggt, alles propper.

So sieht das dann im Log aus:

Wed Mar 23 07:26:19 UTC 2022 Last count of episodes: 16
Wed Mar 23 07:26:19 UTC 2022 Downloading Critical Role Campaign 3 Playlist as json and saving it as cr3.json
Wed Mar 23 07:26:21 UTC 2022 New count of episodes: 16
Wed Mar 23 07:26:21 UTC 2022 Difference is: 0
Wed Mar 23 07:26:21 UTC 2022 There are no new episodes. 
*sad smiley* 
Is it THURSDAY yet?
Wed Mar 23 07:26:21 UTC 2022 New episode count now: 16

Wenn das dann aber von crontab ausgeführt wird, passiert folgendes:

Wed 23 Mar 2022 08:00:01 AM UTC Last count of episodes: 16
Wed 23 Mar 2022 08:00:01 AM UTC Downloading Critical Role Campaign 3 Playlist as json and saving it as cr3.json
Wed 23 Mar 2022 08:00:01 AM UTC New count of episodes: 0
Wed 23 Mar 2022 08:00:01 AM UTC Difference is: -16
Wed 23 Mar 2022 08:00:01 AM UTC There are no new episodes. 
*sad smiley* 
Is it THURSDAY yet?
Wed 23 Mar 2022 08:00:01 AM UTC New episode count now: 0

yt-dlp lädt also offenbar nichts herunter, cr.json bleibt leer, alles geht in die Grütze. Woran liegt das?

Ich geh jetzt mal hin und bastele ne Abfrage mit Abbruch rein, damit mir das verkorkste yt-dlp nicht immer die NOofEpisode zerschießt, aber insgesamt wäre ich für Hilfe sehr aufgeschlossen.

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7790

im cron fehlen gerne PATH und andere Geschichten

vielleicht wird das programm gar nicht gefunden, daher auch die timestamps alle gleich ohne verzögerung

oder ist noch kein netzwerk aktiv wenn der job zu früh ausgeführt wird

speicher dir doch den debugging output mit dann siehst du eher was los ist

kB Team-Icon

Supporter, Wikiteam
Avatar von kB

Anmeldungsdatum:
4. Oktober 2007

Beiträge: 9721

Wohnort: Münster

thom_raindog schrieb:

[…] Der Eintrag in die crontab als @daily läuft zwar, daber geht aber was schief.

Wie hast Du den crontab-Eintrag denn angelegt und in welcher CRON-Tabelle? Und wie sieht diese jetzt aus?

Beachte im Skript: Wenn so etwas von CRON gestartet wird, sind die Umgebungsvariablen anders gesetzt als beim händischen Aufruf. Dies betrifft insbesondere, aber nicht ausschließlich:

  • PATH, wo Programme (= ausführbare Dateien) gefunden werden

  • PWD (= Arbeitsverzeichnis), wo andere Dateien gefunden werden, die gelesen oder geschrieben werden sollen

Du musst Dein Skript so anpassen, dass alle Dateien unter den Ausführungsbedingungen von CRON gefunden werden. Generelle Regel: Wenn Du nicht weist, wie die Umgebungsvariablen gesetzt sind, verwende absolute Pfade zu den Dateien.

thom_raindog

(Themenstarter)
Avatar von thom_raindog

Anmeldungsdatum:
20. Mai 2005

Beiträge: 2848

Ich hab aktuell das Skript unter meinem user in crontab als @hourly:

crontab -l
# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 
# m h  dom mon dow   command
@hourly /home/Ich/bin/CritRoleAutoDownload.sh

Ich hatte halt naiv angenommen, mit dem cd am Anfang würde alles weiter in dem dort angegebenen Verzeichnis laufen, und da liegen alle Dateien.

Irgendwie muss ich aber noch an meiner Fehlerbehandlung arbeiten. Aktuell scheint das Skript abzubrechen, log für den letzten Lauf sieht so aus:

Wed 23 Mar 2022 09:00:01 AM UTC Last count of episodes: 16
Wed 23 Mar 2022 09:00:01 AM UTC Downloading Critical Role Campaign 3 Playlist as json and saving it as cr3.json

Heißt, es bricht beim Aufruf von yt-dlp ab. So sieht das Skript aktuell aus, nachdem ich versuchte, einen im Netz gefundenen Tip umzusetzen:

 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/bash
set -xv #for debugging

error_exit()
{
    echo "Error: $1"
    exit 1
}


BASEPATH="/home/thom/bin"
cd $BASEPATH
PLAYLIST="https://www.youtube.com/watch?v=P8pLvV3FjPc&list=PL1tiwbzkOjQydg3QOkBLG9OYqWJ0dwlxF"
CURRENT=$(<NOofEpisodes)
declare -i DIFFERENCE=0
TARGETPATH="/media/storage/MediaServer/Critical Role/Campaign 3"

echo $(date -u) "Last count of episodes: $CURRENT" >> log.file 2>&1

echo $(date -u) "Downloading Critical Role Campaign 3 Playlist as json and saving it as cr3.json" >> log.file 2>&1

yt-dlp --flat-playlist --print-json "$PLAYLIST" > cr3.json || error_exit "Something went wrong."

#using jq to read cr3.json and output number of episodes.

NEW=$(jq -s length cr3.json)

echo $(date -u) "New count of episodes: $NEW" >> log.file 2>&1

#Calculate $DIFFERENCE. If >0 download as many episodes from playlist
#Substrace NEW from CURRENT; double brackets to transform strings to integers
((DIFFERENCE=$NEW-$CURRENT))
echo $(date -u) "Difference is: $DIFFERENCE" >> log.file 2>&1
#IF DIFFERENCE is >0 start downloading from episode $CURRENT to episode $NEW

if [ $DIFFERENCE -gt 0 ]
then
	echo $(date -u) "There is at least 1 new episode of CR 3. Starting download!" >> log.file 2>&1
	((START=$CURRENT+1))
	yt-dlp -f 22 --playlist-start $START --playlist-end $NEW -P "$TARGETPATH" $PLAYLIST
else
	echo -e $(date -u) "There are no new episodes. \n*sad smiley* \nIs it THURSDAY yet?" >> log.file 2>&1

fi
 
##Writing current episode number to NOofEpisodes
echo $(date -u) "New episode count now: $NEW"  >> log.file 2>&1
echo $NEW > NOofEpisodes

#end debugging
set +xv

thom_raindog

(Themenstarter)
Avatar von thom_raindog

Anmeldungsdatum:
20. Mai 2005

Beiträge: 2848

frostschutz schrieb:

speicher dir doch den debugging output mit dann siehst du eher was los ist

Wie würde ich das denn tun? ☺

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7790

Zur Not mit so einem Wrapper

#!/bin/bash

/voller/pfad/zum/richtigen/script >& /voller/pfad/zur/log/ausgabe

bzw. die Ausgabe Umleitung mit in die Crontab hinein und dann schauen, ob es angelegt wird.

Das richtige Script sollte dann Debugging aktiviert haben. Und ggf. eben auch noch zusätzliche Debugmeldungen ausgeben. z.B. einfach mal das komplette Environment mit ausgeben (set ohne Parameter)

thom_raindog

(Themenstarter)
Avatar von thom_raindog

Anmeldungsdatum:
20. Mai 2005

Beiträge: 2848

Hmm... das hier steht jetzt in meiner crontab

@hourly /home/Ich/bin/CritRoleAutoDownload.sh >& /home/Ich/bin/full.log

Es passiert aber seit dieser Änderung vor 2 Stunden nix mehr...

wxpte

Anmeldungsdatum:
20. Januar 2007

Beiträge: 1388

Heißt, es bricht beim Aufruf von yt-dlp ab. So sieht das Skript aktuell aus, nachdem ich versuchte, einen im Netz gefundenen Tip umzusetzen:

So sieht's aus. Das hatte frostschutz ja schon anhand der einheitlichen Logzeiten (Wed 23 Mar 2022 08:00:01 AM UTC) vermutet. Bei der händischen Ausführung benötigt yt-dlp immerhin ca. zwei Sekunden, um irgendetwas zu machen. Hast du dir die cr3.json denn schon mal angesehen? Vermutlich ist sie nach Ausführung per Cron-Job 0 Bytes groß.

Ich hatte halt naiv angenommen, mit dem cd am Anfang würde alles weiter in dem dort angegebenen Verzeichnis laufen, und da liegen alle Dateien.

Vermutlich liegt da die Ursache. Wenn ich Skripte in Cron laufen lassen will, verlasse ich mich nicht auf den cd-Befehl. Wie du, setze ich zunächst die Pfadvariable:

basis=/home/wxpte/Fernsehen

um dann für jede Datei den absoluten Pfad mitzugeben

wget -q -O '-' ${ax[3]} | fgrep '<td>' | sed -f $basis/tabdelim.ses | grep -vf $basis/Senderliste_Pay-TV.ptv | fgrep -qvf $basis/${ax[1]}.rfl \
&& DISPLAY=:0 feh --geometry +810+460 -x $basis/${ax[1]}.png &

Das hat bis jetzt immer fehlerfrei funktioniert, wenn ich die Skriptdatei per Cron habe aufrufen lassen.

thom_raindog

(Themenstarter)
Avatar von thom_raindog

Anmeldungsdatum:
20. Mai 2005

Beiträge: 2848

Aktuell bin ich nochmal zum händischen Runterladen zurückgekehrt. Ich muss wesentlich mehr Fehlerbehandlung einbauen. Die Tage hat ein Video auf YT mag gemackt, lies sich nicht in Qualität "22" runterladen (mein Standard), woraufhin das Skript selbst händisch an seine Grenzen kam.

Dann werde ich alle Befehle sicherheitshalber mit absolutem Pfad ausführen und mal sehen was bei rum kommt. ☺

Danke.

Antworten |