Bash script: MySQL query over SSH not queried as I want - mysql

I'm trying to run the following over SSH via a BASH script:
for register in ${#:3}; do
ssh host "mysql -u root -pPASSWORD -D DATABASE -e 'CALL DATABASE.domain('$2', '$register');'"
done
Where $2 is e.g "google.com" and $register is another domain which will loop depending how many registered domain I have, e.g "mydomain.com".
When I run the script the query cuts off ".com" only for $2 but inputs the right text for $register. So it looks like this if I use "google.com" and "mydomain.com":
for register in ${#:3}; do
ssh host "mysql -u root -pPASSWORD -D DATABASE -e 'CALL DATABASE.domain('google', 'mydomain.com');'"
done
When I echo out the text I get the full FQDN for $2 but not when I try to run it via mysql.

Related

Escaping out password variable with special characters for mysqldump

I'm trying to create a shell script to automatically backup my whole database. My script expects the password in a new line because I don't want to store it anywhere. Here is my code:
#!/bin/bash
echo -n Password:
read -s PASS
echo
docker exec db /usr/bin/mysqldump --all-databases -u admin --password='\''$PASS\'' > backup-$(date "+%Y-%m-%d").sql
The problem is, that I need to put the variable into single quotes because of the $ signs in the password, but I can't read variables in single quotes.
I know there are several similar questions out there, but I could not solve is with them.
So if the password is '$ecretPa$$word', then the actual executed program should be something like this:
docker exec db /usr/bin/mysqldump --all-databases -u admin --password='$ecretPa$$word' > backup-2020-03-03.sql
I managed to make this work. Maybe the problem was not with the escaping but with the way I tried to run this.
My final code:
#!/bin/bash
echo -n Password:
read -s PASS
echo
cmd="docker exec db /usr/bin/mysqldump --all-databases -u admin --password='$PASS' > backup-$(date "+%Y-%m-%d").sql"
eval "$cmd";

Nested SQL Statement within MYSQL within SSH from bash script

I have the unfortunate situation, that I don't have the permission to access the MYSQL database from outside the server. But SSH is possible. Therefore I try to run a simple SQL statement from a bash file, that creates a SSH connection, connects to the MYSQL DB and run the SQL statement.
The syntax is pretty straight forward but I'm not able to use them combined in one bash file, but on the command line each individual is working
that the snippets I'm using:
1) establish the SSH connection:
$:sshpass -p my_password ssh my_user#my_server
2) connect to the MYSQL DB:
my_server>mysql -h rdbms -u db_user -D db_name -p db_password
3) run the SQL statement
mysql>SELECT * FROM table
... as said. all good when running on command line.
But when I combine them into a bash file:
#!/usr/bin/
sshpass -p my_password ssh my_user#my_server
mysql -h rdbms -u db_user -D db_name -p db_password
SELECT * FROM table
It stops right after the first line (establishing the SSH connection). Any ideas how I can combine these?
To run a command on a remote server via ssh, you need to list the command as arguments on the same command-line.
For example:
sshpass -p my_password ssh my_user#my_server date
That will run date on the remote server, and return the output of that command.
You can run the mysql client this way too. Just put the mysql command on the same command-line, as arguments to your ssh.
sshpass -p my_password ssh my_user#my_server mysql ...arguments...
You can use \ at the end of a line to continue a long command on the following line. It works as if you had written the full command on one very long line, but it's easier to post in Stack Overflow so readers don't have to scroll horizontally to read it. :-)
Also note that the remote command must be in quotes so it appears like a single argument to ssh. When it runs on the remote server, it will be expanded to multiple arguments.
sshpass -p my_password ssh my_user#my_server \
"mysql ...arguments..."
The mysql client has an option -e that you can use to execute an SQL statement.
sshpass -p my_password ssh my_user#my_server \
"mysql -h rdbms -u db_user -D db_name -pdb_password -e 'SELECT * FROM table'"
A couple of tips about the password:
There must be no space between -p and the password. If you use -p with a space after it, you will be prompted for the password interactively. The word following the space is not taken as the password unless you stick it against the -p.
I don't like to put passwords in plaintext on the command-line. It's not safe to do that, because anyone who can access your shell history can view the password. It's better to use an option file or a login file. But you'll have to put these on the remote server where the mysql client runs.

Run MySQL query on remote machine through ssh in command line

I am trying to run MySQL query on remote machine with this command:
ssh user#192.168.2.26 "mysql -uroot -proot -e \"use test";""
I am not able to use that database.
Please suggest a working command.
Try this:
mysql -h host -u root -proot -e "show databases;";
Try this:
ssh root#host "mysql database -e 'query to run on table_name; more queries to run;'"
Same can be done with user#host if that user has permission to execute SQL queries let alone launch mysql in general. Using -e is the same as --execute, which will run whatever you put within the trailing quotes (single or double) and quit. The standard output format would be the same as you would see using --batch.
MySql seems to have a special command line syntax which includes the database.
mysql -u user -p -e 'SQL Query' database
This documentation is rather old but I got it to work
http://www.cyberciti.biz/faq/run-sql-query-directly-on-the-command-line/
Final working command with ssh:
ssh user#host "mysql -u user -e 'show tables;' databasename"
This ended up working for me in a bash script:
query='USE [database]; SELECT ...'
mysql='mysql -u [username] -p[password] -e '"'""$query""'"
ssh [username]#[server] -t "$mysql"
If you want to make it more safe then add a prompt for the password instead of storing it somewhere potentially unsafe.
This worked for me after a few tests (basically same answer as #King-Wzrd):
ssh -t kom "mysql -uroot -p -e 'show databases;'"
ssh -t kom "mysql -uroot -p < /home/ling/websites/jin_test/.deploy/tmp.sql"
The "trick" was the quotes around the command.
The -t option allows for prompting password interactively via the remote shell.
The kom here is just a ssh config identifier defined in my ~/.ssh/config file (see more here: https://www.cyberciti.biz/faq/create-ssh-config-file-on-linux-unix/).
Running this from my Host environment against MySQL within my Homestead VM produced a nice result... although I did have to set the root password from within the VM first in order for it to work.
ssh vagrant#192.168.10.10 mysql -h localhost -u root -p -e "'SELECT * FROM user;' mysql";

execute mysql on remote server via bash script

I need to execute a mysql command on a remote server but seem to be hitting problem when it comes to executing the actual mysql bit
#!/usr/bin/expect -f
spawn /usr/bin/ssh -t root#10.0.0.2
expect "password: "
sleep 1
send "password\r"
sleep 2
/usr/bin/mysql databasename -e "update device_log set status = 'Y' where device_id in ('1','2');"
basically I want to change the flag to Y on device id's 1&2
but the script outputs
invalid command name "/usr/bin/mysql"
Just append the mysql command to the ssh command to run it in one go, like this:
#!/usr/bin/expect -f
spawn /usr/bin/ssh -t root#10.0.0.2 /usr/bin/mysql databasename -e "the query"
expect "password: "
sleep 1
send "password\r"
I'm not very much into expect, but I'm expecting that your attempt in the mysql line isn't actually valid syntax for expect to run a command.
Additionally:
You should use SSH keys for passwordless login instead of having a root password hardcoded in a script.
Consider running MySQL remotely e.g. mysql -h 10.0.0.2 -e "the query", or
Use port forwarding in SSH to connect to MySQL securely, e.g. run ssh -L 3307:localhost:3306 root#10.0.0.2 in the background and then connect to TCP port 3307 on localhost mysql -h 127.0.0.1 -P 3307.
It sounds like /usr/bin/mysql is not the the path to the mysql binary on that remote server. You could use just mysql instead, assuming that the binary is somewhere in that remote server's PATH. Otherwise you will have to go and find out where the binary is actually located and alter the absolute path accordingly.

Making an alias for SSH MySQL login using ENDSSH heredoc

I want to make an alias that is kept in my bashrc file to log into a remote MySQL db via SSH.
Assume that I can't add/alter any files on the remote machine that I'm SSHing into. Here's the relevant code.
function ssh_mysql {
echo "SSHing to $server"
ssh -t -t $suser#$server <<ENDSSH
eval "mysql -h "$host" -u $user -p $pass $db"
ENDSSH
}
alias wt_mysql=ssh_mysql
The Problem: Entering 'wt_mysql' into the terminal as an alias SSHs and logs into MySQL fine.. but when trying to enter any command/query/etc at the MySQL prompt, none of what I've submitted is executed/run. Including the 'exit' command. I have to ctrl C to get back to my local terminal. although its a bit out of my understanding I believe the problem is related to this topic, Terminating SSH session executed by bash script
How can I make sure that mysql and any subsequent commands are executed remotely?
Thanks!
I don't understand why you're using eval (or why you're passing the -t switch twice).
I would expect this ssh command to do what you want:
ssh -t $suser#$server "mysql -h '$host' -u $user -p $pass $db"