3
\$\begingroup\$

I've written a script in an attempt to try to automate moving hosts from old hosts to our new docker containers.

All feedback and input appreciated!

#!/bin/bash

# Generate private public ssh-keys
if [ ! -f "$HOME/.ssh/id_rsa" ] && [ ! -f "$HOME/.ssh/id_rsa.pub" ]; then
        ssh-keygen -b 4096
fi

read -p "Enter your ssh host:" ssh_host
read -p "Enter your ssh username:" ssh_user
read -p "Enter your remote ssh port:" ssh_port

# REMOTE SSH

if [ -z "$ssh_user" ]; then
        echo -e "Config: SSH Username missing"
        echo $ssh_user
        exit
fi

if [ -z "$ssh_host" ]; then
        echo -e "Config: SSH Host is missing"
        exit
fi

if [ -z "$ssh_port" ]; then
        echo -e "Config: SSH Port missing"
        exit
fi

ssh-copy-id $ssh_user@$ssh_host -p $ssh_port -i "$HOME/.ssh/id_rsa" &>/dev/null

# REMOTE DATABASE

read -p "Enter path for wp-config.php:" wp_config_path


# INIT
db_details="cat $wp_config_path/wp-config.php"
scp -P $ssh_port -r $ssh_user@$ssh_host:"$wp_config_path/*" .

# Might be dangerous if file contains malicious input in the values?
eval $(awk -F "[()']" '/^define\(/{printf "%s='\''%s'\''\n", $3, $5;}' < wp-config.php | grep DB_*)

if [ -z "$DB_USER" ]; then
        echo -e "Config: RDB user missing"
        exit
fi

if [ -z "$DB_PASSWORD" ]; then
        echo -e "Config: RDB password missing"
        exit
fi

if [ -z "$DB_NAME" ]; then
        echo -e "Config: RDB name missing"
        exit
fi

dump="mysqldump -u $DB_USER --password='$DB_PASSWORD' $DB_NAME"

read -p "Enter your LOCAL database user:" local_db_user
read -p "Enter your LOCAL database name:" local_db_name
read -s -p "Enter your local database password:" local_db_password

printf "\033c"

ssh $ssh_user@$ssh_host -p $ssh_port $dump | mysql -u $local_db_user --password=$local_db_password $local_db_name

sed -i -e "s;\(define([[:space:]]*'DB_USER',[[:space:]]*\)\(.*\)\()\;\);\1'$local_db_user'\3;g" wp-config.php
sed -i -e "s;\(define([[:space:]]*'DB_PASSWORD',[[:space:]]*\)\(.*\)\()\;\);\1'$local_db_password'\3;g" wp-config.php
sed -i -e "s;\(define([[:space:]]*'DB_NAME',[[:space:]]*\)\(.*\)\()\;\);\1'$local_db_name'\3;g" wp-config.php

echo -e "Database imported to: $local_db_name"
echo -e "Cleaning up..."

# CLEANING UP

# This is bad, and should NEVER be used on hosts with active pub/private key authentication.
ssh $ssh_user@$ssh_host -p $ssh_port 'echo "" > $HOME/.ssh/authorized_keys'

ssh_user=
ssh_host=
ssh_port=
DB_USER=
DB_PASSWORD=
DB_NAME=
local_db_name=
local_db_password=
local_db_user=
wp_config_path=

echo -e "Exiting"
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Just a tip, you could use wp-cli.org in your script (easy db import/export, search/replace, change configuration...). \$\endgroup\$
    – meetjey
    Sep 11, 2016 at 21:06

1 Answer 1

2
\$\begingroup\$

Make input validation more user-friendly

You ask to enter host, user and port, and if one of them is empty you exit. If I entered a host and a user and accidentally pressed enter for port (empty), I would be very unhappy with the script.

It would be better to put the prompting logic in a loop, and repeat forever until a non-empty value is entered. Ideally in a function, to reduce code duplication.

Exit with non-zero code on error

When exiting with error, it's recommended to use a non-zero exit code.

~ is the same as $HOME

I prefer writing ~ because it's shorter.

Use printf instead of echo -e

The flags of echo are not portable. To get the behavior of echo -e, I suggest to make it a habit to use printf instead.

Replace awk + grep with just awk

In this command you use a combination of awk and grep:

eval $(awk -F "[()']" '/^define\(/{printf "%s='\''%s'\''\n", $3, $5;}' < wp-config.php | grep DB_*)

You can do what grep does here in awk, which will be more efficient. The difference will be negligible in this example, but it's good to make it a habit to avoid additional processes when easily possible.

Replace multiple sed calls when one is enough

This code rewrites the same file 3 times:

sed -i -e "s;\(define([[:space:]]*'DB_USER',[[:space:]]*\)\(.*\)\()\;\);\1'$local_db_user'\3;g"

wp-config.php sed -i -e "s;(define([[:space:]]'DB_PASSWORD',[[:space:]])(.)()\;);\1'$local_db_password'\3;g" wp-config.php sed -i -e "s;(define([[:space:]]'DB_NAME',[[:space:]])(.)()\;);\1'$local_db_name'\3;g" wp-config.php

One sed would be enough, using multiple -e parameters.

Pointless cleaning up

Resetting the variables at the end of the script seem pointless. This is only useful if you source this script, which seems unlikely. If you run this script (as opposed to sourcing it), then the variables you defined or modified will not be visible after the script has completed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.