Bash Script, prüfen ob Backup älter als 10 Tage.

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Knogle
Beiträge: 466
Registriert: 06.05.2016 19:29:00
Lizenz eigener Beiträge: MIT Lizenz

Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von Knogle » 10.02.2019 17:23:03

Ich grüße euch liebe Community.
Aktuell habe ich ein Script welches Backups von Minecraft Servern erstellt, dabei wird das Backup mit folgender Syntax erstellt.

Code: Alles auswählen

"${Backuppath}Minecraft_Modded_Backup_${SERVICE}_$(date +%Y-%m-%d_%H-%M).7z"
Also bspw.

Code: Alles auswählen

Minecraft_Modded_Backup_enigmatica.jar_2019-01-27_03-00.7z
Nun will ich jedoch eine Funktion einbauen, welche alle Backups löscht die Älter als 10 Tage alt sind.
Also in dem Fall vom

Code: Alles auswählen

Minecraft_Modded_Backup_enigmatica.jar_2019-01-27_03-00.7z
Alle Backups die vor dem hier erstellt wurden

Code: Alles auswählen

Minecraft_Modded_Backup_enigmatica.jar_2019-01-17_03-00.7z
Wie kann ich sowas bewerkstelligen?

Oder kann man evtl. auch ueber irgendeinen Befehl das Erstelldatum der Datei abfragen, und so vergleichen?

Code: Alles auswählen

#!/bin/bash
# /etc/init.d/minecraft
# version 0.4.2 2016-02-09 (YYYY-MM-DD)
#
### BEGIN INIT INFO
# Provides:   minecraft
# Required-Start: $local_fs $remote_fs screen-cleanup
# Required-Stop:  $local_fs $remote_fs
# Should-Start:   $network
# Should-Stop:    $network
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description:    Minecraft server
# Description:    Starts the minecraft server
### END INIT INFO

#Settings
SERVICE="${2}.jar"
SCREENNAME=$2
OPTIONS='nogui'
USERNAME='root'
WORLD='world'
MCPATH="/home/minecraft_servers/${2}/"
MINHEAP=4096
HISTORY=4096
CPU_COUNT=8
Xms=1G
JAVACMD="java"
MAX_RAM="8192M"     # -Xmx
JAVA_PARAMETERS="-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=${CPU_COUNT} -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:+AggressiveOpts -Xms${Xms}"
INVOCATION="${JAVACMD} -server -Xmx${MAX_RAM} ${JAVA_PARAMETERS} -jar ${SERVICE} nogui"
Backuppath="/minecraft/modded/"
Zielordner="${Backuppath}Minecraft_Modded_Backup_${SERVICE}_$(date +%Y-%m-%d_%H-%M).7z"
Password="FASkog4AmtO1XIvGbkh8sqppYs51Eo7E7drbVpCSXOIsX4yyaUsIXvVEnLGQELMh3n1eqI23QiOGVhnsnlCX7GGMQKVapKCfoqnei2u8Ssb7ZDgbbbfYgpoo0DT"




ME=`whoami`
as_user() {
  if [ "$ME" = "$USERNAME" ] ; then
    bash -c "$1"
  else
    su - "$USERNAME" -c "$1"
  fi
}

mc_start() {
  if  pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is already running!"
  else
    echo "Starting $SERVICE..."
    cd $MCPATH
    as_user "cd $MCPATH && screen -h $HISTORY -dmS ${SCREENNAME} $INVOCATION"
    sleep 7
    if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
      echo "$SERVICE is now running."
    else
      echo "Error! Could not start $SERVICE!"
    fi
  fi
}

mc_saveoff() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is running... suspending saves"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-off\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
  else
    echo "$SERVICE is not running. Not suspending saves."
  fi
}
mc_port(){


	  grep -n 'server-port=' "$MCPATH/server.properties"


}

mc_saveon() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is running... re-enabling saves"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-on\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
  else
    echo "$SERVICE is not running. Not resuming saves."
  fi
}

mc_stop() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "Stopping $SERVICE"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-all\"\015'"
    sleep 10
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"stop\"\015'"
    sleep 7
  else
    echo "$SERVICE was not running."
  fi
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "Error! $SERVICE could not be stopped."
  else
    echo "$SERVICE is stopped."
  fi
}

mc_update() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is running! Will not start update."
  else
    as_user "cd $MCPATH && wget -q -O $MCPATH/versions --no-check-certificate https://launchermeta.mojang.com/mc/game/version_manifest.json"
    if [ "$1" == "snapshot" ] ; then
      JSONVERSION=`cd $MCPATH && cat versions | python -c "exec(\"import json,sys\nobj=json.load(sys.stdin)\nversion=obj['latest']['snapshot']\nfor v in obj['versions']:\n   if v['id']==version:\n    print(v['url'])\")"`
    else
      JSONVERSION=`cd $MCPATH && cat versions | python -c "exec(\"import json,sys\nobj=json.load(sys.stdin)\nversion=obj['latest']['release']\nfor v in obj['versions']:\n   if v['id']==version:\n    print(v['url'])\")"`
    fi
    as_user "cd $MCPATH && wget -q -O $MCPATH/versions --no-check-certificate $JSONVERSION"
    MC_SERVER_URL=`cd $MCPATH && cat versions | python -c 'import json,sys;obj=json.load(sys.stdin);print(obj["downloads"]["server"]["url"])'`
    as_user "rm $MCPATH/versions"
    as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update --no-check-certificate $MC_SERVER_URL"
    if [ -f $MCPATH/minecraft_server.jar.update ] ; then
      if `diff $MCPATH/$SERVICE $MCPATH/minecraft_server.jar.update >/dev/null` ; then
        echo "You are already running the latest version of $SERVICE."
      else
        as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/$SERVICE"
        echo "Minecraft successfully updated."
      fi
    else
      echo "Minecraft update could not be downloaded."
    fi
  fi
}

mc_backup() {


if [ ! -d "${MCPATH}" ]; then
    echo "MCPATH existiert nicht!"
    exit 1
fi
if [ -d "${Zielordner}" ]; then
    echo "Zielordner bereits vorhanden!"
    exit 1
fi
if [ ! -d "${Backuppath}" ]; then
    echo "Backuppath existiert nicht!"
	as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say Backuppath does not exist!\"\015'"
    exit 1
fi
mc_saveoff
#Check if there is sufficient space on backup disk. Available space must be greater than max. occupied space.
reqSpace=$(df "$MCPATH/$SERVICE" | awk 'NR==2 { print $4 }') 
availSpace=$(df "$HOME" | awk 'NR==2 { print $4 }')
if (( availSpace < reqSpace )); then
  as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say Not enough space available on backup drive!\"\015'"
  echo "Nicht genug Speicherplatz frei!" >&2
  exit 1
fi

#-p"${Password}" has been removed.
7z a -t7z -mx=1 -m0=LZMA2 -mmt=${CPU_COUNT} "${Zielordner}" "${MCPATH}" >> "${Backuppath}placeholder.txt"
7z h -scrcsha256 "${Zielordner}" >> "${Backuppath}placeholder.txt"
as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say Filename: ${Backuppath}\"\015'"
mc_saveon
}

mc_command() {
  command="$1";
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    pre_log_len=`wc -l "$MCPATH/logs/latest.log" | awk '{print $1}'`
    echo "$SERVICE is running... executing command"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"$command\"\015'"
    sleep .1 # assumes that the command will run and print to the log file in less than .1 seconds
    # print output
    tail -n $[`wc -l "$MCPATH/logs/latest.log" | awk '{print $1}'`-$pre_log_len] "$MCPATH/logs/latest.log"
  fi
}

#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  update)
    mc_stop
    mc_backup
    mc_update $2
    mc_start
    ;;
  backup)
    mc_backup
    ;;
  port)
	mc_port
	;;
  status)
    if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
      echo "$SERVICE is running."
    else
      echo "$SERVICE is not running."
    fi
    ;;
  command)
    if [ $# -gt 1 ] ; then
      shift
      mc_command "$*"
    else
      echo "Must specify server command (try 'help'?)"
    fi
    ;;

  *)
  echo "Usage: $0 {start|stop|update|backup|status|restart|command|port \"server command\"}"
  exit 1
  ;;
esac

exit 0

TomL

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von TomL » 10.02.2019 18:17:24

Knogle hat geschrieben: ↑ zum Beitrag ↑
10.02.2019 17:23:03
Nun will ich jedoch eine Funktion einbauen, welche alle Backups löscht die Älter als 10 Tage alt sind.
Die Aufnahmen meines Cam-Systems lösche ich regelmäßig im 4 Stunden-Zyklus, also alle jpg's, die älter als 12 Stunden sind. Das müsste man passend abändern können:

Code: Alles auswählen

/usr/bin/find /media/FTP -maxdepth 2 -type f -iname "*.jpg" -mmin +720 -exec /bin/rm '{}' \;

Knogle
Beiträge: 466
Registriert: 06.05.2016 19:29:00
Lizenz eigener Beiträge: MIT Lizenz

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von Knogle » 10.02.2019 19:03:56

Ich danke dir sehr dafuer!
Ich muss nun nur noch hinkriegen, dass man Wildcards gebrauchen kann beim Dateinamen, dann ist es perfekt!

Code: Alles auswählen

"/usr/bin/find ${Backuppath} -maxdepth 2 -type f -name '*${SERVICE}*.7z' -mmin +$MINUTES -exec /bin/rm '{}' \;"
Hat jemand da einen Tipp? ${SERVICE} ist bspw. enigmatica.

tobo
Beiträge: 2336
Registriert: 10.12.2008 10:51:41

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von tobo » 10.02.2019 22:51:08

Warum ist denn da die ganze Zeile mit " gequotet? Das '*${SERVICE}*.7z' darf nicht in einfachen ' Anführungszeichen, sondern muss in doppelten " Anführungszeichen stehen, damit die Variable expandiert werden kann. Sofern es keinen Grund dagegen gibt, sollten alle Variablen bei der Benutzung (Auslesen) durch " eingeschlossen werden. Also so: "*${SERVICE}*.7z". Die ${}-Schreibweise ist da im Übrigen kein Ersatz dafür - die grenzt nur die Variable ab bzw. lässt zusätzlich noch shell-spezifische Überprüfungen zu. Da wird nichts gequotet.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von heinz » 11.02.2019 17:05:43

Ein Problem was ich dabei sehe:
Wenn ueber laengere Zeit kein neues Backup gemacht wird, aus welchen Gruenden auch immer,
dann sind nach ein paar Tagen alle Backups weg...
Vlt. waere es sinnvoller, eine max. Anzahl von Backups festzulegen.
Z.B. 5
Und wenn es mehr als 5 sind werden die aeltesten Backups geloescht.
Auf diese weise haette man wenigstens immer ein Backup...

Gruss, heinz

Knogle
Beiträge: 466
Registriert: 06.05.2016 19:29:00
Lizenz eigener Beiträge: MIT Lizenz

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von Knogle » 11.02.2019 17:18:39

Das klingt gut! Aber wie kann man das gut bewerkstelligen?
Kann ich auch irgendwie mit 7z die Ordnerberechtigungen und Besitzer übernehmen?
Momentan mache ich das so.

Code: Alles auswählen

7z a -t7z -mx=1 -m0=LZMA2 -mmt=${CPU_COUNT} "${Zielordner}" "${MCPATH}" >> "${Backuppath}placeholder.txt"
7z h -scrcsha256 "${Zielordner}" >> "${Backuppath}placeholder.txt"

TomL

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von TomL » 11.02.2019 18:21:14

Knogle hat geschrieben: ↑ zum Beitrag ↑
11.02.2019 17:18:39
Aber wie kann man das gut bewerkstelligen?
Das ist ganz einfach zu bewerkstelligen, ohne das man sich auch noch ums löschen kümmern muss... nummeriere die Backups einfach durch, beginnend bei 0, dann fortlaufend immer eins drauf. Wenn die von Dir vorgegebene maximale Anzahl von Backups erreicht ist, fängst Du wieder bei 0 an und überschreibst damit die alte Version 0.

Angenommen, du legst 10 als größte Anzahl Backups fest, bestehen nach dem Überschreiben der 0 (wenn ein Zyklus durchgelaufen ist) noch die älteren Backus von 1-9. Wird 1 überschrieben bestehen die Versionen 2-9 + 1, wenn 2 überschrieben wird, bestehen die Versionen 3-9 + 0-1, usw. Das heisst, Du hast immer ein aktuelles Backup plus 9 absteigend ältere. Weil man immer gleiche Dateinamen hat, z.B. BackupHD1_0 bis BackupHD1_9 ist das Handling total easy via Script umzusetzen.

Ich habe das beispielsweise über Tag-im-Monat geregelt, als Beispiel: jeden 1, jeden 6., jeden 12., jeden 18., jeden 24. Das ist dann noch einfacher, weil man die "Zahl" einfach aus dem Datum ableiten kann, man spart sich einen Zähler mitzuschlören. Die Backups überschreiben sich alle im Laufe der Zeit mit dieser Zahl im Namen rotierend und es liegen trotzdem immer mehrere unterschiedlich alte Versionen vor. Ums löschen muss ich mich dabei nicht kümmern, das ist seit längerem ein völlig wartungsfreier selbstläufer.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von heinz » 11.02.2019 18:33:55

@TomL
Tolle Idee, super einfach umzusetzen! :THX:

pferdefreund
Beiträge: 3799
Registriert: 26.02.2009 14:35:56

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von pferdefreund » 12.02.2019 10:00:49

IBM konnte das schon seit den 70er Jahren mit MVS. Da gab es genau für diese Zwecke das generation-Dataset - kurz GDG genannt (gibt es übrigens auch heute noch unter Z/OS). Die haben es halt schon immer drauf gehabt.

Knogle
Beiträge: 466
Registriert: 06.05.2016 19:29:00
Lizenz eigener Beiträge: MIT Lizenz

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von Knogle » 14.02.2019 16:01:04

Danke euch! Habe das nun eingebunden.
Jedoch will ich das ganze nun um einen Restore Befehl erweitern.

Code: Alles auswählen

  restore)
    if [ $# -gt 1 ] ; then
      shift
      mc_restore "$*"
    else
      echo "Restoring failed. (try 'help'?)"
    fi
    ;;
Das Datum des Backups soll als 3. Parameter eingegeben werden, also bspw. so

Code: Alles auswählen

./script restore enigmatica 2019-02-14_15-36
Jedoch klappt das nicht, und ich bekomme folgendes heraus.

Code: Alles auswählen

/minecraft/modded/final+frontier.jar/Minecraft_Modded_Backup_final+frontier 2019-02-14_15-36.7z
Das Leerzeichen dazwischen, ich weiss nicht wo das herkommt.



Das echo habe ich bisher nur zu debugzwecken drin.

Und wie kann ich bspw. den uebergeordneten Ordner von ${MCPATH} angeben? Irgendwie sowas? {${MCPATH}../}

Code: Alles auswählen

mc_restore() {

BACKUPDATE=${3}

if [ ! -e "${Backuppath}Minecraft_Modded_Backup_${SERVICE}_${BACKUPDATE}.7z" ]; then

	echo "${Backuppath}Minecraft_Modded_Backup_${SERVICE}_${BACKUPDATE}.7z"
    echo "Backup file with specified name doesn't exist!"
	exit 1
fi

mc_stop
sleep 15
echo "Restoring.. Backup ${Backuppath}Minecraft_Modded_Backup_${SERVICE}_${BACKUPDATE}.7z"
sleep 5
as_user "rm -r ${MCPATH}"
as_user "cp ${Backuppath}Minecraft_Modded_Backup_${SERVICE}_${BACKUPDATE}.7z /home/minecraft_servers/"
as_user "7z x ${Backuppath}Minecraft_Modded_Backup_${SERVICE}_${BACKUPDATE}.7z" > /dev/null
sleep 30
as_user "chown -R minecraft_servers:minecraft_servers ${MCPATH}"
mc_start

}
Ist es auch machbar Befehle erst auszufueren, wenn bspw. das Unzippen durch ist?

Benutzeravatar
MegaV0lt
Beiträge: 173
Registriert: 21.11.2011 11:16:07
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: Bash Script, prüfen ob Backup älter als 10 Tage.

Beitrag von MegaV0lt » 14.02.2019 16:51:20

Für das erste Problem würde ich "$@" statt "$#" verwenden.

Warten kann die Bash auf selbst gestartete Processe mit wait. Einfach mal testen
"Das Internet? Gibt's diesen Blödsinn immer noch?"
[Homer Simpson], Sicherheitsinspektor im Kernkraftwerk Springfield.

Antworten