在terminal中使用mysql来取消警告消息,但使用bash脚本编写密码

当我试图在terminal内运行MySQL的以下命令时:

mysql -u $user -p$password -e "statement" 

执行按预期工作,但始终发出警告:

警告:在命令行界面上使用密码可能不安全。

但是,我必须使用一个存储我的密码的环境variables( $password )来执行上面的语句,因为我想从terminal内的bash脚本中迭代运行该命令,而且我绝对不喜欢等待提示出现并迫使我在一个脚本中input我的密码50或100次。 所以这是我的问题:

  • 抑制警告是否可行? 这个命令正如我所说的那样工作正常,但是当我循环并运行命令50或100次时,窗口变得非常混乱。

  • 我应该遵守警告信息,不要在我的脚本中写密码吗? 如果是这样的话,那么每次提示强迫我时都必须input我的密码吗?

运行man mysql并没有帮助,只是说

--show-warnings
如果有任何陈述,会在每个陈述后显示警告。 该选项适用于交互式和批处理模式。

并没有提到如何closuresfunction,如果我不丢失的东西。

我在OS X 10.9.1小牛,并从自制软件使用MySQL 5.6。

如果您的MySQL客户端/服务器版本是5.6.xa的方式,以避免WARNING消息正在使用mysql_config_editor工具:

 mysql_config_editor set --login-path=local --host=localhost --user=username --password 

那么你可以在你的shell脚本中使用:

 mysql --login-path=local -e "statement" 

代替:

 mysql -u username -p pass -e "statement" 

我使用类似于:

 mysql --defaults-extra-file=/path/to/config.cnf 

要么

 mysqldump --defaults-extra-file=/path/to/config.cnf 

其中config.cnf包含:

 [client] user = whatever password = whatever host = whatever 

这使您可以拥有多个configuration文件 – 针对不同的服务器/angular色/数据库。 使用〜/ .my.cnf将只允许你有一组configuration(尽pipe它可能是一组有用的默认设置)。

如果您使用的是基于Debian的发行版,并以root身份运行,则可以跳过上述步骤,只需使用/etc/mysql/debian.cnf即可获取…:

mysql --defaults-extra-file=/etc/mysql/debian.cnf

一种方便(但同样不安全)的方法是使用:

 MYSQL_PWD=xxxxxxxx mysql -u root -e "statement" 

请注意,官方文件build议反对它。
请参阅6.1.2.1密码安全最终用户指南(版本5.6的Mysql手册) :

将密码存储在MYSQL_PWD环境variables中

这种指定你的MySQL密码的方法必须被认为是非常不安全的 ,不应该被使用。 一些版本的ps包括一个选项来显示正在运行的进程的环境。 在某些系统上,如果您设置了MYSQL_PWD ,则您的密码将暴露给运行ps的任何其他用户。 即使在没有这种ps版本的系统上,假设没有其他用户可以检查过程环境的方法也是不明智的。

如果您希望在命令行中使用密码,我发现这适用于筛选出特定的错误消息:

 mysqlcommand 2>&1 | grep -v "Warning: Using a password" 

它基本上是将标准错误redirect到标准输出 – 并使用grep删除所有符合“警告:使用密码”的行。

这样,您可以看到任何其他输出,包括错误。 我用这个为各种shell脚本等

下面是我如何让我的日常mysqldump数据库备份的bash脚本更安全地工作。 这是Cristian Porta伟大的答案的扩展。

  1. 首先使用mysql_config_editor (附带mysql 5.6+)来设置encryption的密码文件。 假设你的用户名是“db_user”。 从shell提示符运行:

     mysql_config_editor set --login-path=local --host=localhost --user=db_user --password 

    它提示input密码。 一旦你input,用户/密码就会被encryption保存在你的home/system_username/.mylogin.cnf

    当然,将“system_username”更改为服务器上的用户名。

  2. 从这改变你的bash脚本:

     mysqldump -u db_user -pInsecurePassword my_database | gzip > db_backup.tar.gz 

    对此:

     mysqldump --login-path=local my_database | gzip > db_backup.tar.gz 

没有更多的暴露密码。

指定loginpath时,还可以在脚本中运行mysql_config_editor以传递密码

 expect -c " spawn mysql_config_editor set --login-path=$mySqlUser --host=localhost --user=$mySqlUser --password expect -nocase \"Enter password:\" {send \"$mySqlPassword\r\"; interact} " 

这会启动一个预期会话,可以在脚本中使用,以便与提示进行交互

看到这个职位

https://gist.github.com/nestoru/4f684f206c399894952d

 # Let us consider the following typical mysql backup script: mysqldump --routines --no-data -h $mysqlHost -P $mysqlPort -u $mysqlUser -p$mysqlPassword $database # It succeeds but stderr will get: # Warning: Using a password on the command line interface can be insecure. # You can fix this with the below hack: credentialsFile=/mysql-credentials.cnf echo "[client]" > $credentialsFile echo "user=$mysqlUser" >> $credentialsFile echo "password=$mysqlPassword" >> $credentialsFile echo "host=$mysqlHost" >> $credentialsFile mysqldump --defaults-extra-file=$credentialsFile --routines --no-data $database # This should not be IMO an error. It is just a 'considered best practice' # Read more from http://thinkinginsoftware.blogspot.com/2015/10/solution-for-mysql-warning-using.html 

最简单的方法是

 mysql -u root -pMYPASSWORD -e "show databases" 2>/dev/null 

另一种select是使用sshpass来调用mysql,例如:

 sshpass -p topsecret mysql -u root -p username -e 'statement' 
 shell> mysql_config_editor set --login-path=local --host=localhost --user=localuser --password Enter password: enter password "localpass" here shell> mysql_config_editor set --login-path=remote --host=remote.example.com --user=remoteuser --password Enter password: enter password "remotepass" here 

要查看mysql_config_editor写入.mylogin.cnf文件的内容,请使用print命令:

 shell> mysql_config_editor print --all [local] user = localuser password = ***** host = localhost [remote] user = remoteuser password = ***** host = remote.example.com 

print命令将每个loginpath显示为一组行,以表头中的方括号中的loginpath名开头,后面跟随loginpath的选项值。 密码值被屏蔽,不会显示为明文。

如上例所示,.mylogin.cnf文件可以包含多个loginpath。 通过这种方式,mysql_config_editor可以很容易地设置多个“个性”来连接到不同的MySQL服务器。 当您调用客户端程序时,可以使用–login-path选项通过名称select其中的任何一个。 例如,要连接到本地服务器,请使用以下命令:

 shell> mysql --login-path=local 

要连接到远程服务器,请使用以下命令:

 shell> mysql --login-path=remote 

就我个人而言,我使用脚本包装来捕捉错误。 这里是代码示例:

 #!/bin/bash #echo $@ | cat >> /home/mysqldump.log 2>/dev/null ERR_FILE=/tmp/tmp_mdump.err # Execute dumper /usr/bin/mysqldump $@ 2>$ERR_FILE # Determine error and remove tmp file ERROR=`cat $ERR_FILE` rm $ERR_FILE # Handle an error if [ "" != "$ERROR" ]; then # Error occured if [ "Warning: Using a password on the command line interface can be insecure." != "$ERROR" ]; then echo $ERROR >&2 exit 1 fi fi 

另一个解决scheme(例如脚本):

  sed -i'' -e "s/password=.*\$/password=$pass/g" ~/.my.cnf mysql -h $host -u $user $db_name -e "$sql_cmd" 

-i''选项在这里是为了与Mac OS X兼容。标准的UNIX操作系统可以直接使用-i

你可以使用/ dev / null来执行mySQL并禁止警告和错误消息,例如:

 # if you run just a SQL-command mysql -u ${USERNAME} -p${PASSWORD} -h ${HOST} ${DATABASE} -e "${STATEMENT}" &> /dev/null # Or you can run SQL-script as a file mysql -u ${USERNAME} -p${PASSWORD} -h ${HOST} ${DATABASE} < ${FILEPATH} &> /dev/null 

哪里:

 ${USERNAME} - existing mysql user ${PASSWORD} - password ${HOST} - ip or hostname, for example 'localhost' ${DATABASE} - name of database ${STATEMENT}- SQL command ${FILEPATH} - Path to the SQL-script 

请享用!

我遇到的问题是在bash脚本中使用条件输出。

这不是优雅,但在docker环境这应该真的没关系。 基本上所有这一切都是忽略不在最后一行的输出。 你可以用awk做类似的事情,并改变返回除第一行之外的所有内容。

这只会返回最后一行

 mysql -u db_user -pInsecurePassword my_database ... | sed -e '$!d' 

它不会抑制这个错误,但是它会确保你可以在bash脚本中使用查询的输出。

一个简单的workaroud脚本。 命名这个“mysql”,并把它放在“/ usr / bin”之前的path中。 其他命令的明显变体,或者警告文本不同。

 #!/bin/sh ( ( ( ( ( /usr/bin/mysql "$@" ) 1>&9 ) 2>&1 ) | fgrep -v 'mysql: [Warning] Using a password on the command line interface can be insecure.' ) 1>&2 ) 9>&1 

它为我工作 – 只是在$(mysql_command)之后添加2> null ,它只会抑制错误和警告消息。