Escaping curly braces in shell script - mysql

I have a script to dump my databases, like this :
#!/usr/bin/env sh
PATH=/usr/bin:/bin
LOG="mybackup/log/backup_$(date +%Y-%m-%d_%H:%M:%S).log"
# some other command
# backup mysql database
echo "Backing up database" > ~/$LOG
mysqldump -u myusername -pmypassword --ignore-table={db1.table1,db1.table2,db1.table3,db1.table4} db1 -r ~/mybackup/db/db1_$(date +%Y-%m-%d_%H:%M:%S).sql >> ~/$LOG 2>&1
# some other command
When I run the command in terminal, it successfully dump my database without ignored tables. But when I run the command through the script, it dump all tables in the database.
I have tried to escape the curly braces :
mysqldump -u myusername -pmypassword --ignore-table=\{db1.table1,db1.table2,db1.table3,db1.table4\} db1 -r ~/mybackup/db/db1_$(date +%Y-%m-%d_%H:%M:%S).sql
but it still dump all table.
My question is how to escape braces/brackets properly in shell script?

I can't answer why it DOES work on command line, but the documentation says to use the option multiple times:
mysqldump --ignore-table documentation
man mylsqdump
--ignore-table=db_name.tbl_name
Do not dump the given table, which must be specified using both the
database and table names. To ignore multiple tables, use this option
multiple times. This option also can be used to ignore views.

Related

Run mysql commands in bash script without logging in or adding -u root to every command

I'm writing a bash script to do some db stuff. New to MySQL. I'm on Mac and have MySQL installed via homebrew.
Am using username "root" right now and there isn't a pw set. I included the pw syntax below just to help others out that may have a pw.
My goal is to have mysql commands be as "clean" as possible in my bash script
Not a hige deal, but would like to do this if possible.
Example
# If I can do it without logging in (*ideal)
mysql CREATE DATABASE dbname;
# Or by logging in with - mysql -u root -pPassword
CREATE DATABASE dbname;
# Instead of
mysql -u root -pPassword -e"CREATE DATABASE dbname";
Tried to simplify it. I have a handful of things I gotta do, so would rather keep my code cleaner if possible. I tried logging in with the bash script, but the script stopped once logged into MySQL and didn't run any commands.
Another option I was considering (but don't really like) would be just to keep username and pw string in a var and call it for every commmand like so
# Set the login string variable
login_details="-u root -p password -e"
# example command
mysql $login_details"CREATE DATABASE dbname";
So any ideas?
Write a new bash script file and run this file after putting all your commands into it. Don't forget to give right username and password in your bash script.
For bash script:
#!/bin/bash
mysql -u root -pSeCrEt << EOF
use mysql;
show tables;
EOF
If you want to run single mysql command.
mysql -u [user] -p[pass] -e "[mysql commands]"
Example:
mysql -h 192.168.1.10 -u root -pSeCrEt -e "show databases"
To execute multiple mysql commands:
mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"
Note: -B is for batch, print results using tab as the column separator, with each row on a new line. With this option, mysql does not use the history file. Batch mode results in nontabular output format and escaping of special characters. -s is silent mode. Produce less output. -e is to execute the statement and quit

Export data with complex queries command line mysql

I'm retrieving data from MYSQL databases with a .bat file. The bat file have the next structure
mysql.exe -b -r -u USER -pPASSWORD DATABASE -h IP -e "QUERY" > "PATH\example.txt"
My problem is with complicate queries. I have a query wit multiples joins, and another with asterisk, but doesn't work. I can run the queries perfectly in Navicat but in command line like the code above is impossible.
It is there a way to run this queries without changing the methodology of command line?.
The queries usually have inner join and left joins
Instead of providing the query through the -evalulation flag as a string, you could provide a SQL script file instead for reusability, then direct that in as standard-in to be executed by mysql, then direct the standard-out like you have been doing.
All-in-all, something like this
shell> mysql -b -s -r --username=USER --password=PASSWORD -h HOST db_name < script.sql > output.tab

How to avoid "use <database>" statement on mysqldump backups?

I'm using this command syntax :
mysqldump -u<username> -p<password> --no-create-db --databases mydatabase > /var/backups_DB/MyDatabase-$(date +"%d-%m-%Y-%H:%M:%S").sql
But I could not find how to prevent the line "use mydatabase" to be inserted in the generated file.
Which option should I use?
Exactly. Remove --databases...
https://www.computerhope.com/unix/mysqldum.htm
--databases
-B
Dump several databases. Normally, mysqldump treats the first name argument on the command line as a database name and following names as table names. With this option, it treats all name arguments as database names. CREATE DATABASE and USE statements are included in the output before each new database.
As #wchiquito said in comments, in order to avoid to have the "USE databasename" statement in dump file you must remove the --databases option.
If you don't have the choice, you can remove it afterwards using a Unix sed command :
cat sourcefile.sql | sed '/USE `databasename`;/d' > destfile.sql
Thomas

mysql database backup with mysqldump

I want to backup my database using mysql dump. This is the code I run in Command prompt when the location is mysql bin.
mysqldump -u root -pabc Db -r C:\Documents and Settings\All Users\Desktop\ttttt.sql
abc is the password. and I try to backup to a .sql file in desktop. I use mysql 5.5.
But the following error occured. mysqldump: Couldn't find table: "and"
But there is no table called 'and' in database and I didn't create such a table.But the error say about a 'and' table. How can I back up mysql database without this error.
Try instead:
mysqldump -u root -pabc Db -r "C:\Documents and Settings\All Users\Desktop\ttttt.sql"
Your command shell is breaking apart the pathname into multiple arguments. The quotes tell the shell to pass it all as a single argument to the mysqldump program.
I think there is some problem with syntax of command you are running. try something like this :
mysqldump -u root -p dbName > path\nameOfFile.sql
It will automatically ask for your password. You don't need to write it in command.

How to skip a table when restoring mysql database?

I have a big mySQL database dump named forum.sql. I want to restore only one table, but when I restore the full database, it takes a long time to import the "post" table.
Is there any option to restore this database skipping the "post" table?
If you are restoring from a dump file, you can easily build a new dumpfile without this table, just by writting down the line numbers.
Initial line
> grep dumpfile.sql -ne "Dumping data for table \`avoid_tablename\`" -m 1
43:-- Dumping data for table `avoid_tablename`
Total lines
> wc -l dumpfile.sql
63 dumpfile.sql
Make a new file
> head -n 43 dumpfile.sql > dumpfile-lite.sql
> tail -n 20 dumpfile.sql >> dumpfile-lile.sql
20 comes from substracting 63 - 43
not clean, but usefull
Alternatively, extract the table(s) that need to be restored from fulldump.sql using sed:
sed -n -e '/CREATE TABLE.*tableName1/,/CREATE TABLE/p' fulldump.sql > temp.sql
sed -n -e '/CREATE TABLE.*tableName2/,/CREATE TABLE/p' fulldump.sql >> temp.sql
...etc
Now restore from temp.sql.
Restore a single table
First, do the restore with zero inserts:
cat dump.sql | grep -v '^INSERT INTO' | mysql -u <user> -p<pw> <dbname>
Using grep -v here will exclude any statements matching the pattern. The pattern in this case uses ^ to match at the beginning of a line. The result should be a restored schema with zero data.
Next, restore only your desired INSERT statements:
cat dump.sql | grep '^INSERT INTO \\\`<table>\\\`' | mysql -u <user> -p<pw> <dbname>
That will restore data only for the table named <table>. Note the triple backslashes. You need a backslash to escape a backtick and then you need to escape the backslash with 2 more backslashes.
Restore everything except one table
Another technique I use all the time when I want to restore an entire database but exclude the data from a table or two is this... You can filter out any unwanted INSERT statements by passing your dump through a filter before pushing into the db. Here's an example using grep as the filter:
nohup sh -c "cat dump.sql | grep -v 'INSERT INTO \\\`<table>\\\`' | mysql -u <user> -p<pw> <dbname>" &
The nohup command will keep the sh command running even if you log out of your shell. That can be pretty handy if you have a large dump file that will take quite some time to restore.
The -v flag for grep will exclude anything matching the pattern.
The & at the end will send the command to the background.
As far as I know, no.
You would have to manually edit the CREATE and INSERT statements of the undesired table out of the dump file.
I don't think you can do it. But you can dump tables separately when necessary, using --tables myqsldump option. So, you can generate a dump for post table and another dump for the remaining tables.
Example:
mysqldump -u USERNAME -pPASSWORD --tables TABLE_NAME database_name > TABLE_NAME.sql
You could alter your dump statement so that it uses ignore table? http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_ignore-table