I'm trying to execute this:
$ mysql --user=XXX --password=XXX --batch --skip-column-names \
-e "SELECT userid, displayname FROM Users" stackoverflowdb | \
split -l 50 -a 5 - "result."
but bash complains about ) 'unexpected' character (i have this character and few other 'weird ones' in my mysql password). I tried to take my password in quotes --password="myweirdpasshere" but then mysql won't login me at all (probably password is incorrect?)
Some characters such as $, `, ", and sometimes \ retain their special meaning inside double quotes. If your password contains any of those characters, use single quotes instead. (Unless your password also contains single quotes, in which case you might just drop the quotes altogether and put a \ before each special character.)
You should be able to put the password in the $HOME/.my.cnf file, avoiding this issue as well as increasing the security.
Another option to using $HOME/.my.cnf is embedding the configuration file into the script. A comment on the documentation gives examples on this. For your case it should be:
$ mysql --user=XXX --defaults-file <(printf '[client]\npassword=XXX\n') \
--batch --skip-column-names \
-e "SELECT userid, displayname FROM Users" stackoverflowdb | \
split -l 50 -a 5 - "result."
If you don't give the password on the command line, it will bring up an interactive prompt. That might solve your error. Just use -p instead of --password=XXX.
Of course, if you require unattended access to the script, that's not a very useful answer. It would be more helpful if you could create a minimal example and tell us the exact error that Bash gives you.
Related
I what to write a shell script to loging in to mariadb. The shell script read one password containing special characters(blank, !#) in a ini file.
The OS is Ubuntu 18.04
the ini file as follows:
user=xxx-xxx-xxx
password=xxx /xxx /xx/ !\#
the shell script as follows:
#!/bin/bash
baseDir="$(cd "$(dirname "$0")" && pwd)"
iniPath="$baseDir/backup.ini"
echo "iniPath is $iniPath"
dbUser="$(grep 'user' $iniPath | cut -d '=' -f 2)"
echo "user is $dbUser"
dbPassword="$(grep 'password' $iniPath | cut -d '=' -f 2)"
echo "password is $dbPassword"
mysql -h localhost -u $dbUser -p'$dbPassword'
if I input the command as follows:
mysql -h localhost -u xxxxxx -p'xxx /xxx /xx/ !#'
in command line, it loging successfully.
But If I execute the shell script, it always results in accessing denied for user.
Have any suggestions? thanks.
Have you tried to use: mysql -h localhost -u $dbUser -p'echo $dbPassword' ? (special character ` is on US like keyboards under esc key left upper corner, it looks like back apostroph) Looks like the variable with password is not correctly "printed" into a mysql command before its run. Other way I would recommend trying is to use -p"$dbPassword"
FWIW, the issue is that the shell will not interpolate variables into a string surrounded by single quotes. As Honza specified, the double-quotes will work.
See Difference between single and double quotes in Bash for details.
I've the following bash script to upgrade my database schema. Script reads hostname and database password from command line.
The problem is here that if the password is alphanumeric e.g r00t then script works. But if password contains special characters e.g pa**w0rd, then script does not work and directly exits. Please help me with this. Thanks.
#!/bin/bash
echo "Enter hostname."
read -p "Hostname [localhost]: " DB_HOST
DB_HOST=${DB_HOST:-localhost}
echo "Enter MySQL root password"
DB_PASS=
while [[ $DB_PASS = "" ]]; do
read -sp "Password: " DB_PASS
done
MYSQL="mysql --force --connect-timeout=90 --host=$DB_HOST -u root --password=${DB_PASS}"
# Apply schema updates. My DBName is "mydb"
# Upgrade schema file is stored in "mysql" folder
$MYSQL mydb -e exit > /dev/null 2>&1 && $MYSQL mydb < "../mysql/upgrade_schema_v.2.1.sql"
Logging into mysql using bash
For ubuntu or linux shell try to use command
mysql -u username -p'p#ssw()rD'
for remote host login use
mysql -h hostname -u user -p'password'
This is occurring because you are using shell GLOB (wildcard) characters in the password, and in Bash (or on Linux generally) wildcards are expanded by the shell.
The safest and most reliable solution is to not use shell wildcard characters or other characters interpreted by the shell in the password. You should also avoid spaces. There are plenty of other characters.
Here are the ones you should avoid:
" ' $ , [ ] * ? { } ~ # % \ < > | ^ ;
Here are the ones it is usually safe to use:
: # . , / + - ! =
To ensure the password is still secure, make it longer. As an example:
K#3amvv7l1wz1192sjqhym
This meets old-fashioned password complexity rules, because upper, lower, numbers and special characters are in the first four, the remainder is randomly generated but avoids any problematic characters.
However if you must use them, you can quote the password parameter with single quotes - though you will still run in to trouble if the password contains single quotes!
Try enclosing your password in single quotes.
If it's pa**w0rd, use 'pa**w0rd'
Variables are best used for data, not code. The layers of variables make it hard to protect the expansion when you want some parts of the expansion (i.e., you want your command line to be word split on the tokens you want), but don't want all the other effects. The solution is to not store the code in a string. Instead, use a function like:
do_mysql() {
host="$1"
pass="$2"
mysql --force --connect-timeout=90 --host="$host" -u root --password="$pass" "$#"
}
then you can run it with extra arguments like
do_mysql "$DB_HOST" "$DB_PASS" -e exit > /dev/null && do_mysql "$DB_HOST" "$DB_PASS" < "../mysql/upgrade_schema_v.2.1.sql"
Though it would also be better not to use upper case for your variables. Doing so makes it so you could collide with environment variables and accidentally change things you don't intend to change (as the number of people who accidentally reset PATH can attest).
I am trying to execute an insert statement from linux shell where one of the columns has '$2a$10$zKjqmgld1gDYB/qkDuAS' in the value. When I see the inserted data the value is truncated and I get only 'aKjqmgld1gDYB/qkDuAS' as any digit followed by dollar is treated by linux as a parameter passed to the script.
This is how I am executing the script
mysql -u user --password=password -e "insert into users(id,name,password) values(1,'Some Name','\$2a\$10\$zKjqmgld1gDYB/qkDuAS')"
I have even tried escaping the $ like \$2a\$10\$zKjqmgld1gDYB/qkDuAS, but still it yields the same truncated data , however when I do echo '\$2a\$10\$zKjqmgld1gDYB/qkDuAS', I get the entire thing back.
Sameer
Single quotes don't nest in shell (do they anywhere else, anyway?). So, your string is effectively outside the quotes. Combine with double quotes and backslashes:
mysql -u user --password=password -e \
"insert into users(id,name,password) values(1,'Some Name','\$2a$10\$zKjqmgld1gDYB/qkDuAS')"
it was already in double quotes (sorry, for writing the wrong query). That didn't work either, however I found a workaround
echo "insert into users(id,name,password) values(1,'Some Name','\$2a\$10\$zKjqmgld1gDYB/qkDuAS')" >> temp.sql
mysql -u user --password=password < temp.sql
This finally worked.
I wrote a MySQL command in bash (Ubuntu) :
[XXXX:~]$ mysql -h localhost -u XXXX -pXXXX -e "DROP DATABASE IF EXISTS `f-XXXX`;"
I need backquote in this command, cause database name is variable.
That command doesn't work and it sends f-XXXX command not found
I think my problem is related to backquotes. How can I do?
You need not use backtick for variable substitution here.
[XXXX:~]$ mysql -h localhost -u XXXX -pXXXX -e "DROP DATABASE IF EXISTS ${DB};""
Bash takes the content of the backtick and runs another bash process with that as a command.
This is a backtick. Backtick is not a quotation sign, it has a very special meaning. Everything you type between backticks is evaluated (executed) by the shell before the main command (like chown in your examples), and the output of that execution is used by that command, just as if you'd type that output at that place in the command line.
Use $(commands) instead.
mysql -h localhost -u XXXX -pXXXX -e "DROP DATABASE IF EXISTS $('f-XXXX');"
I tried to execute the following mysql command in one of my scripts:
mysql -e 'show global status like 'open_files''
But it doesn't seem to work, because of the single quotes around the string 'open_files'.
How can I issue a command like this, that contains a single quote?
Use double quote outside.
mysql -h127.0.0.1 -uxxxxx -pxxxxx -A databasename -e "show global status like 'open_files'"
or the reverse way:
mysql -h127.0.0.1 -uxxxxx -pxxxxx -A databasename -e 'show global status like "open_files"'
or you could escape the single quote.
And you are using LIKE, didn't you miss the wild char %?