I have a CakePHP database.php config file that I'd like to leverage to open a command line mysql
client instance.
The goal would be to be able to run a shell script like ./db-login.sh
from the project root and have it pull the database details (host, port, database name, username, password) from the PHP config file and pass them to the mysql
command line as arguments. This is to avoid having to enter the details every time.
I understand it's possible to create a shell alias that has the values hard-coded: I would like a portable script that could be included with any of my Cake projects. I also would like to keep the task of getting the DB credentials into bash variables separate from launching the mysql
client. This would open up the ability to re-use the DB credentials in other shell scripts easily (such as a mysqldump
backup script.)
Here's what I have so far:
database.php
Consider this file immutable for the purposes of this question. It must exist exactly as you see it.
<?php
class DATABASE_CONFIG {
public $default = array(
'host' => 'localhost',
'login' => 'cakephpuser',
'password' => 'c4k3 roxx!',
'database' => 'my_cakephp_project',
);
}
db-cred.sh
Acts as middleware to convert the PHP variables into bash (friendly) variables.
#!/usr/bin/env php
<?php
include 'database.php';
$db = new DATABASE_CONFIG();
// Selectively wrap quotes. Has no real effect(?)
$p = (!empty($db->default['password']) ? "\"$db->default['password']\"" : '');
echo <<<EOD
DB_HOST="{$db->default['host']}"
DB_NAME="{$db->default['database']}"
DB_USER="{$db->default['login']}"
DB_PASS={$p}
EOD;
db-login.sh
#!/usr/bin/env bash
# Uses Cake's database.php file to log into mysql on the
# command line with the correct arguments.
# Holy yuck, but nothing else works!
eval $( db-cred.sh )
# Try to set an appropriate password clause.
PATTERN=" |'"
if [ -n "$DB_PASS" ]; then
if [[ $DB_PASS =~ $PATTERN ]]; then
PASS_CLAUSE=" -p'${DB_PASS}'"
else
PASS_CLAUSE=" -p${DB_PASS}"
fi
else
PASS_CLAUSE=""
fi
# Get a rough look at what we're about to run.
echo mysql --host=${DB_HOST} --database=${DB_NAME} --user=${DB_USER}${PASS_CLAUSE}
# Call MySQL.
mysql --host=${DB_HOST} --database=${DB_NAME} --user=${DB_USER}${PASS_CLAUSE}
Things that need help:
- The
db-login.sh
script uses eval to suck in the variables. Yuck. - The MySQL password is leaked on the command line. This is not a dealbreaker, but if there's a clean/portable way to avoid it, I'm open to it.
- Spaces and quotes in the mysql password don't get passed to bash properly.
- A password like
my Pass
will cause DB_PASS to be set tomy
indb-login.sh
. - Quoting the string in
db-cred.sh
produces"my
instead.
- A password like
- Likewise, my attempts at quoting
PASS_CLAUSE
are not effective: Only passwords without spaces/quotes will successfully log into themysql
client.