Aus Raspberry Pi Geek 08/2022

Download-Manager für die Shell (Seite 2)

Funktionen

Ähnlich wie mit den Variablen verfahren Sie am besten auch mit Funktionen. Es empfiehlt sich, sie so zu gestalten, dass sie möglichst unabhängig voneinander in diesem und eventuell anderen Skripten koexistieren.

Wenn es bei einer Funktion nicht so leicht ersichtlich ist, wie viele Parameter sie entgegennimmt und was sie zurückgibt, beschreiben Sie das in Kommentaren. Die Funktion erfassung kümmert sich um das Erfassen und Abspeichern der in der Webseite enthaltenen Links. Listing 4 legt erst einmal drei Arrays an, die die Funktionen mit Werten füllen. Das erste Array speichert die URLs ab und bearbeitet sie.

Da das Skript die Downloads nach Größe ordnen soll, ermittelt Wget diese mit der Option --spider (Zeile 12). Danach erfasst das Array indizierte_downloads die Datei, die sich herunterladen lässt, indem es als Index die Dateigröße verwendet und als Wert den Namen des Downloads selbst (Zeile 15). Dadurch gibt es für das Array nicht die typischen Indexe wie 0, 1, 2, 3 und so weiter, sondern beispielsweise 233, 1004, 780 etc., die die Bash beim Auflisten aller Indexe der Größe nach aufsteigend ausgibt. Das geschieht auch in der Zeile 19, wo das Arrayindizierte_indexe die Größen der Dateien abgespeichert.

Sie sehen später, dass die möglichen Downloads der Größe nach aufsteigend erscheinen. Es kommt gelegentlich auch vor, dass zwei Dateien dieselbe Größe aufweisen. Das fängt aber die While-Schleife in den Zeilen 13 bis 17 ab. Damit sich dieser Index für den Download eignet, erhöht das Skript in diesem Fall die angezeigte Größe um ein (virtuelles)) Byte.

Listing 4

Funktionen

declare -a download_links
declare -a indizierte_downloads
declare -a indizierte_indexe
function erfassung () {
  lynx_options="-dump -listonly -nonumbers" # weitere mögliche Optionen
  lynx_befehl="lynx $lynx_options $url"     # -hiddenlinks=[option], -image_links
  grep_suchstring="http.+($(sed 's/ /|/g' <<<${dateitypen[@]}))$"
  grep_befehl="grep -Eoi $grep_suchstring"
  download_links=(`$lynx_befehl | $grep_befehl`)
  for x in ${download_links[@]}; do
    datei_gr=$(wget --spider $x 2>&1 | gawk -F " " '/Länge/{print $2}')
    while true; do
      [ -z ${indizierte_downloads[$datei_gr]} ] &&
      indizierte_downloads[$datei_gr]=$x &&
      break || (( datei_gr++ ))
    done
  done
  indizierte_indexe=(${!indizierte_downloads[@]})
}

Kurz und schmerzlos

In Listing 5 sehen Sie eine Funktion, die für das vernünftige Aufsplitten der Auswahl an Downloads sorgt. Sie treffen nach dem Auflisten der Downloads die Auswahl, indem Sie zum Beispiel 1,2,3,4-10 eintippen. In diesem Fall übernimmt das Skript die Downloads von 1 bis 10, die dann in der Form von (1:*2 3:*4 ...) in einem Array landen.

Die Funktion splitter befreit den String von Kommas und erstellt von Bereichen wie 4-10 eine sortierte, durch Leerzeichen getrennte Zahlenfolge. Mithilfe dieser Auswahlnummern findet Sie im späteren Verlauf die Downloads, die das Array indizierte_downloads enthält.

Behalten Sie schon einmal im Hinterkopf, dass bei Arrays der Bash die Zählung immer ab 0 beginnt. Wählen Sie beispielsweise die Datei Nummer 5 aus, dann finden Sie diese durch Abfrage von indizierte_indexe[4]. Denselben Index verwenden Sie beim Array indizierte_downloads, um den dazugehörigen Wert abzufragen.

Listing 5

Auswahl aufsplitten

function splitter () {
  sed 's/,/\n/g' <<<$* | sed -r '/-/ s/([0-9]+)-([0-9]+)/seq \1 \2/e' | sort -nu
}

Listing 6 zeigt die Funktion, die beim Herunterladen das Umbenennen der Dateien übernimmt. Ihr übergeben Sie als Parameter den Basisnamen der URL. Das Skript befindet sich zu diesem Zeitpunkt schon im passenden Verzeichnis für die Dateiendung, wie etwa jpg/. Die Parameter ab Zeile 3 lokalisieren andere Dateien, die sich vor dem Start des Downloads schon darin befinden. Die Bash prüft mit dem Kommando aus Zeile 4, ob eine Namensgleichheit vorliegt. Falls ja, dann fügt das Skript zwischen dem Namen und dem Punkt vor der Endung einen Unterstrich (_) ein. Daraus ersehen Sie auch, wie oft die Datei umbenannt wurde. Zeigt der Name einen Unterstrich, wurde die Datei einmal umbenannt, zeigt er zwei, war es zwei Mal der Fall, und so weiter.

Listing 6

Umbenennen

function umbenennen () {
  dateiname=$1
  andere_dateinamen=`echo ${@:2}`
  while grep -q -F "${dateiname}" <<<${andere_dateinamen}; do
    dateiname=$(sed -r 's/(.+)(\.)(.+)/\1_\2\3/' <<<${dateiname})
  done
  echo ${dateiname}
}

Es schadet an dieser Stelle auch nicht, zwischendurch Funktionen im Einzelnen zu debuggen, indem Sie diese isolieren. Mit Sed und dem Kommando aus Listing 7 würden Sie beispielsweise die Funktionen warn und umbenennen in eine separate Datei schreiben, wo Sie sie im Anschluss mit dem Befehl bash -x debug debuggen, indem Sie innerhalb der Datei etwa die Funktion umbenennen und mit den dazugehörigen Parametern aufrufen.

Listing 7

Debuggen

$ cat <(sed -r -n '/function (warn|umbe)/,/^}/p' downloader_optimiert2.bash) > debug

Listing 8 zeigt die Funktion für den Download. Als Erstes filtert sie den Basisnamen aus dem Download-Link heraus. Dazu löscht sie alle Pfadangaben sowie http://... oder https://..., bis nur noch der eigentliche Dateiname übrig bleibt. Das Skript ermittelt im weiteren Verlauf die Dateiendung und legt, sofern noch nicht vorhanden, ein Verzeichnis mit diesem Namen an. Anschließend wechselt es dorthin und startet nach dem Durchlauf der Funktion umbenennen das Herunterladen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 6 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben