Hello everyone!
I had a container with a DB crap itself yesterday so I’m trying to speed up my learning to back up stuff.
I came across a script that taught me how to back-up a containerized postgres db at given intervals and it works. I managed to create db dumps and restore them. I’ve documented everything and now my whole docker-compose/env etc are on git control.
There’s one part of the script I don’t decypher but I’d like to maybe change it. It is about the number of back-up copies.
Here’s the line from the tutorial:
ls -1 /backup/*.dump | head -n -2 | xargs rm -f
Can someone explain to me what this line does? I’d like to keep maybe 3 copies just in case the auto-backup backs up a rotten one.
Thanks!
Full code below:
backup:
    image: postgres:13
    depends_on:
      - db_recipes
    volumes:
      - ./backup:/backup
    command: >
      bash -c "while true; do
        PGPASSWORD=$$POSTGRES_PASSWORD pg_dump -h db-postgresql -U $$POSTGRES_USER -Fc $$POSTGRES_DB > /backup/$$(date +%Y-%m-%d-%H-%M-%S).dump
        echo ""Backup done at $$(date +%Y-%m-%d_%H:%M:%S)""
        ls -1 /backup/*.dump | head -n -2 | xargs rm -f
        sleep 86400
      done"
- Ah! This is a shell pipe! It’s composing several smaller commands together, cool stuff. - 
ls -1is the grep-friendly version of ls, it prints one entry per line, like a shopping list.
- 
headtakes a set number of entries from the head of a list, in this case2 items.negative two, meaning “all but the last two.”
- 
xargstakes the incoming pipe and converts it into extra arguments, in this case applying those arguments torm.
 - So, combined, this says “list all the .dump files, pick - the first two,all but the last two, and delete them.” Presumably the first are the oldest ones and the last are the newest, if the .dump files are named chronologically.
- 
- The first command (ls -1 /backup/*.dump) just creates a list of files in the backup folder that have the extension .dump. the output of the prior command is then sent to the next command (head -n -2) this cuts the list down to everything except the last 2 items in the list this is then sent to the final command which takes the list and runs the final (rm -f) command with the items in the list as the targets to delete. - heres a solution based on this post https://stackoverflow.com/questions/25785/delete-all-but-the-most-recent-x-files-in-bash - ls -tp /backup/*.dump | grep -v ‘/$’ | tail -n +4 | tr ‘\n’ ‘\0’ | xargs -0 rm -f - There is an explanation on that post that explains it in better detail but in simple terms it deletes all files but the most recent 3 files in the directory that have the .dump extension 
- Others have explained the line. - Worth noting that not all implementations of head accept negative line counts (i.e. last n lines), and you might substitute tail. - i.e.: ls -1 /backup/*.dump | tail -2 | xargs rm -f - Won’t this delete the two newest files, as opposed to everything except the two newest files? 
 

