Making an alias for SSH MySQL login using ENDSSH heredoc - mysql

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"

Related

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.

Bash script for interactive ssh and mysql commands

I'm studying MySQL, and every time I have to
Enter ssh XXX#XXX command, and enter my password to the school server.
Enter mysql -u XXX -p command, and enter MySQL password.
I want to create a Bash script for performing the steps above automatically.
I can accomplish the first step with this code:
#!/usr/bin/expect -f
set address xxx.com
set password xxx
set timeout 10
spawn ssh xxx#$address
expect { "*yes/no" { send "yes\r"; exp_continue} "*password:" { send "$password\r" } }
send clear\r
interact
But I don't know how to automatically input the next command (mysql -u xxx -p) and the password.
How can I do this?
You don't need such a complex script to just enter the MySQL console on remote machine. Use the features of the ssh tool:
ssh -tt user#host -- mysql -uuser -ppassword
The -t option forces pseudo-terminal allocation. Multiple -t force tty allocation, even if ssh has no local tty (see man ssh). Note the use of -p option. There must be no spaces between -p and password (see the manual for mysql).
Or even connect via mysql directly, if the MySQL host is accessible from your local machine:
mysql -hhost -uuser -p
Don't forget to adjust the shebang:
#!/bin/bash -
Use my.cnf to store your password securly like ssh keys.
https://easyengine.io/tutorials/mysql/mycnf-preference/
Same way ssh is also possible through ssh -i parameter and passing the private key path of the remote host.
Best of luck!

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.

ssh connection and remote output in local shell

I would like to run a local command file remotely and get the output locally in my shell window.
Actually the command executes remotely but I do not see the results in my local shell/console window.
Any idea on how to implement the following command?
ssh user#host 'bash -s' < /Users/daniel/bin/bash/fz_multiple_db_connections.sh
Where fz_multiple_db_connections.sh contains:
#!/bin/bash
connections=(
'mysql -u dbuser__name --password=passw dbname '
'mysql -u dbuser__name1 --password=passw1 dbname1')
for f in "${connections[#]}"
do
echo `${f}`
echo `mysql show tables`
echo `mysql exit`
done
exit
I think you'll probably need to do ssh -t .... to allocate a tty. Programs that strictly write to stdout or std::cout should work fine without the -t, but if the program you're running needs access to /dev/tty (or any of it's equivalents), for example, to ask for a password or something, you need the -t option to ssh.
-v verbose output
http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch07_03.htm