Skip to content

Bash script to simplify Sendy updates

edited May 2018 in Contributions

Hello guys, Ben, hope everything is ok there.

I deal with 6 Sendy installations for customers that have purchased the license, and every time a new version is released, the manual updating task is time consuming. So, I wrote this bash script to automatically update the installation, and after a couple iterations and corrections, I now have it working as a breeze and without errors.

Although, since this require the cPanel account containing the script to be able to provide access to jailed shell, I really would love to avoid this and have it in the form of PHP script, or even better, bundled as a feature of Sendy itself :) Hopefully, someone can provide that.

In the meantime, here I share the script for those who may need something alike, or even to point out fixes or improvements.

For this script to work, you must run it as the user. If you use cPanel, then first allow jailed shell to that account, and by connecting via SSH, you will land on /home/username, then create a blank file, and assign execution permssions to it: chmod +x

Then paste the below code inside. Take into account:

  • For CentOS 6.x replace /bin/sh with /bin/bash
  • Replace [license] with your actual license string.

    #! /bin/sh
    cd ./public_html;
    wget[license] -O;
    cp .htaccess sendy/.htaccess;
    cp includes/config.php sendy/includes/config.php;
    cp -R sendy/* .;
    rm sendy -drf;
    rm -f;
    chmod -R ugo-x,u+rwX,go+rX,go-w ./;

Then save, and to execute simply run: ./ If everything went well, it should not throw any errors. After execution is completed, go to your browser and login to your Sendy installation and it will automatically update the database accordingly. Just try to perform these tasks in hours where no emails are being sent, or at least notify you customers to schedule the process with enough anticipation in order to avoid any kind of issues.

Please consider this script was coded under CentOS 7.5 with cPanel. Other environments may have distinct rules/paths and you should always make a trustworthy backup before trying this solution. In my personal case, it updated Sendy in just 2 seconds.

Hope it helps anybody interested in this solution. And of course I'm open to suggestions.

All the best,


  • Wow, nice script... thanks you !

  • Thank you, me too implemented this on my server...

  • edited June 2018

    Brilliant - thanks.

    I added a little backup to /tmp/ and removed the uploads directory from the new update just in case. Change the /var/www/html to where ever your sendy install is.

    #! /bin/sh
    cd /var/www/html; 
    tar -cvf /tmp/sendybackup.tar .
    wget[license]  -O;
    cp .htaccess sendy/.htaccess;
    rm -rf /sendy/uploads
    cp includes/config.php sendy/includes/config.php;
    cp -R sendy/* .;
    rm sendy -drf;
    rm -f;
    chmod -R ugo-x,u+rwX,go+rX,go-w ./;

  • Thanks for this bash script!
    I concur with the idea of a php script! It would be great to have a magical update button somewhere in the Sendy interface. :)
    I am sure a php script can be easily devised to make it painless.

  • edited June 2018

    I would use curl -O -J -L in case the URL ever starts using redirects.

  • Having automated update would be wonderful.

  • If some of you are using translations (in my case fi_FI) you need to copy those over to the new version:

    mkdir /var/www/html/my.domain/sendy/locale/fi_FI cp -R /var/www/html/my.domain/public_html/locale/fi_FI /var/www/html/my.domain/sendy/locale/ cp -R /var/www/html/my.domain/public_html/uploads/ /var/www/html/my.domain/sendy

    --- pls replace /var/www/html/my.domain/ with your own path to Sendy

  • edited June 2021

    Hi guys! I'm using the code below and does anyone have any tips how can I check the health of sendy?

    mkdir -p $UPDATE_PATH/backup \
    && mysqldump --opt --user=$SENDY_DB_USER --password=$SENDY_DB_PASS -h $SENDY_DB_HOST $SENDY_DB_BASE | gzip -c > $UPDATE_PATH/backup/sendy_db-$(date +%y%m%d%H%M).sql.gz \
    && tar -c $PUBLIC_PATH | gzip -c > $UPDATE_PATH/backup/sendy-$(date +%y%m%d%H%M).tar.gz \
    && unzip $UPDATE_PATH/ -d $UPDATE_PATH \
    && rm -rf $UPDATE_PATH/sendy/.htaccess $UPDATE_PATH/sendy/includes/config.php \
    && cp -R $UPDATE_PATH/sendy/* $PUBLIC_PATH/
    # to do: check health for to reverse or remove backup

    Ricardo Belo

  • edited June 2021

    Hi Sendy users,

    I just wanted to provide an update based on @marcelop's original post, that combines a couple of extras, some of which were explored/noted by subsequent commenters. For reference, I am using CPanel, and therefore, @marcelop's original post should be read before using the code I've included below.

    My Objectives

    In addition to being able to automatically download, unzip and install the latest Sendy package, I needed to be able to:

    1. Backup the database

    2. Backup the existing Sendy installation files (web root)

    3. Store both files and database backups outside of the web root

    4. Ensure that my .htaccess file was maintained after updating

    5. Ensure that my uploads directory was maintained after updating

    6. Ensure that my custom API directory lists was maintained after updating

    Further, I wanted to be able to use CURL to avoid potential issues should Sendy implement redirects on the updates page (as noted by (@savonaequipment) in the future.

    In order to achieve this, I'm using the following which is executed from my home/[username] directory with the command ./

    The Code

    N.B. I've commented the code heavily in the hope that this may help some noobs who might otherwise struggle to edit the file appropriately, in addition to declaring configuration vars at the top, to make editing a bit easier. It is cited in the comments, but please also note, that the $BACKUP_DIR var MUST be relative to the $PUBLIC_PATH since it is the directory in which we are working - hence the var being named BACKUP_DIR not _PATH.

    #! /bin/sh
    #----------------------------- CONFIG ---------------------------------------
    # Update the following details insinde the quotation marks
    SENDY_LICENSE="YOUR_SENDY_LICENSE"; # enter your sendy license here
    PUBLIC_PATH="./public_html"; # Enter the path of your sendy public directory, relative from your user directory where this script is stored
    BACKUP_DIR="../backup"; # Enter a backup directory path here, relative to your PUBLIC_PATH - "../backup" sits alongside "public_html" in this example 
    SENDY_DB_HOST="YOUR_DATABASE_HOST"; # Enter your Database host (IP/URL/localhost) - same as your config.php
    SENDY_DB_NAME="YOUR_DATABASE_NAME"; # Enter your Database name - same as your config.php
    SENDY_DB_USER="YOUR_DATABASE_USER"; # Enter your Database Username - same as your config.php
    SENDY_DB_PASS="YOUR_DATABASE_PASSWORD"; # Enter your Database password - same as your config.php
    #---------------------------- //END CONFIG ----------------------------------
    # Change into configured $PUBLIC_PATH relative to your home/user (typically 'public_html')
    cd $PUBLIC_PATH; 
    # Backup the Current Sendy files into a ZIP into the configured $BACKUP_DIR with file name appended with the current date/time.
    tar -cvf $BACKUP_DIR/sendy-files-$(date +%y%m%d%H%M%S).tar .;
    # Backup the DB as a ZIP using the crededntials, appending the current date/time to the filename
    mysqldump --opt --user=$SENDY_DB_USER --password=$SENDY_DB_PASS -h $SENDY_DB_HOST $SENDY_DB_NAME | gzip -c > $BACKUP_DIR/sendy-db-$(date +%y%m%d%H%M%S).sql.gz
    # Download the new Sendy Update into the current ($PUBLIC_PATH) directory, renaming it for ease of removing later.
    curl -o$SENDY_LICENSE -L
    # Unzip (results in $PUBLIC_PATH/sendy)
    # Copy the .htaccess from the live site, to the new sendy update dir
    cp .htaccess sendy/.htaccess;
    # Copy the current config.php from the live site, to the new sendy update dir
    cp includes/config.php sendy/includes/config.php;
    #-------------------- CUSTOM --------------------
    # REMOVE TO '# //END: CUSTOM' or change as appropriate 
    # to backup any of your custom files, changing the 
    # directory names as required
    mkdir sendy/api/lists; # CUSTOM - create my custom API subdir in the sendy update (Comment out/remove if not needed)
    cp api/lists/* sendy/api/lists; # copy my custom API files to the sendy update (Comment out/remove if not needed)
    # //END: CUSTOM ---------------------------------
    # Delte the uploads directory from the sendy update, in order your current uploads directory isn't overwritten
    rm -rf sendy/uploads;
    # Copy everything that's now in the $PUBLIC_PATH/sendy dir to the $PUBLIC_PATH dir, overwriting existing
    cp -R sendy/* .;
    # Remove the $PUBLIC_PATH/sendy directory
    rm sendy -drf;
    # Remove the $PUBLIC_PATH/ file
    rm -f;
    # Update permissions
    chmod -R ugo-x,u+rwX,go+rX,go-w ./;

    Thanks to everyone in this thread who's contributed to this!! I hope this helps someone out!

    I will look at a PHP implementation of this at some point but a hectic schedule and heavy workload means this down and dirty version will suffice for the time being.



Sign In or Register to comment.