Suppress warning messages using mysql from within Terminal, but password written in bash script
当我尝试从终端内部在mysql上运行以下命令时:
1 | mysql -u $user -p$password -e"statement" |
执行按预期工作,但始终发出警告:
Warning: Using a password on the command line interface can be insecure.
但是,我必须使用存储我的密码的环境变量(
禁止警告是否可行?正如我所说的,命令工作正常,但是当我循环运行命令50或100次时,窗口会变得相当混乱。
我应该遵守警告信息而不在脚本中写密码吗?如果是这种情况,那么每次提示强制我输入密码时,是否都必须输入密码?
运行EDOCX1[1]没有帮助,只说
--show-warnings
Cause warnings to be shown after each statement if there are any. This option applies to interactive and batch mode.
如果我没有遗漏什么,也没有提到如何关闭功能。
我使用的是OS X 10.9.1 Mavericks,使用的是自制的MySQL5.6。
如果您的MySQL客户机/服务器版本是5.6.x,则避免警告消息的方法是使用MySQL_-config_编辑器工具:
然后可以在shell脚本中使用:
1 |
而不是:
1 | mysql -u username -p pass -e"statement" |
我使用类似的东西:
1 |
或
1 |
其中config.cnf包含:
这允许您拥有多个配置文件-用于不同的服务器/角色/数据库。使用~/.my.cnf只允许您使用一组配置(尽管它可能是一组有用的默认值)。
如果您使用的是基于Debian的发行版,并且以根用户身份运行,那么您可以跳过上面的内容,只需使用/etc/mysql/debian.cnf就可以进入……:
一种方便(但同样不安全)的方法是使用:
1 | MYSQL_PWD=xxxxxxxx mysql -u root -e"statement" |
请注意,官方文件对此提出了反对意见。见6.1.2.1最终用户密码安全指南(5.6版MySQL手册):
Storing your password in the
MYSQL_PWD environment variableThis method of specifying your MySQL password must be considered extremely insecure and should not be used. Some versions of ps include an option to display the environment of running processes. On some systems, if you set
MYSQL_PWD , your password is exposed to any other user who runs ps. Even on systems without such a version of ps, it is unwise to assume that there are no other methods by which users can examine process environments.
如果您希望在命令行中使用密码,我发现这可以过滤出特定的错误消息:
1 | mysqlcommand 2>&1 | grep -v"Warning: Using a password" |
它基本上将标准错误重定向到标准输出——并使用grep删除所有与"警告:使用密码"匹配的行。
这样,您就可以看到任何其他输出,包括错误。我将它用于各种shell脚本等。
以下是我如何获得每日mysqldump数据库备份的bash脚本,以更安全地工作。这是克里斯蒂安·波塔伟大答案的扩展。
首先使用mysql_config_editor(与mysql 5.6+一起提供)设置加密的密码文件。假设您的用户名是"db_user"。从shell提示运行:
它提示输入密码。输入后,用户/通行证将被加密保存在您的
当然,将服务器上的"系统用户名"更改为您的用户名。
从此处更改bash脚本:
1 | mysqldump -u db_user -pInsecurePassword my_database | gzip > db_backup.tar.gz |
对此:
1 |
不再暴露密码。
最简单的方法是
1 |
您还可以在脚本中运行mysql_-config_编辑器,在指定登录路径时传递密码。
1 2 3 4 5 | expect -c" spawn mysql_config_editor set --login-path=$mySqlUser --host=localhost --user=$mySqlUser --password expect -nocase "Enter password:" {send "$mySqlPassword "; interact} " |
这将启动一个Expect会话,该会话可在脚本中用于与提示交互。
看到这个帖子
1 2 3 4 5 6 |
要查看mysql_config_editor向.mylogin.cnf文件写入的内容,请使用print命令:
1 2 3 4 5 6 7 8 9 |
print命令将每个登录路径显示为一组行,从一个以方括号表示登录路径名的组头开始,后跟登录路径的选项值。密码值被屏蔽,不显示为明文。
如前面的示例所示,.mylogin.cnf文件可以包含多个登录路径。通过这种方式,mysql_-config_-editor可以轻松设置多个用于连接不同mysql服务器的"个性化"。以后调用客户机程序时,可以使用--login路径选项按名称选择其中任何一个。例如,要连接到本地服务器,请使用以下命令:
1 |
要连接到远程服务器,请使用以下命令:
1 | shell> mysql --login-path=remote |
来自https://gist.github.com/nestoru/4F684F206C399894952d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # 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 |
您还可以将标准错误stderr输出重定向到/dev/null。
所以就这样做:
一个简单的解决方案脚本。将此命名为"mysql",并将其放在路径中"/usr/bin"之前。其他命令的明显变体,或者警告文本不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/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 |
以下是docker在脚本/bin/sh中的解决方案:
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo"[client]"> /root/mysql-credentials.cnf'
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo"user=root">> /root/mysql-credentials.cnf'
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo"password=$MYSQL_ROOT_PASSWORD">> /root/mysql-credentials.cnf'
docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec mysqldump --defaults-extra-file=/root/mysql-credentials.cnf --all-databases'
替换[mysql_container_name]并确保在容器中设置了环境变量mysql_root_password。
希望它能像帮助我一样帮助你!
另一种选择是使用sshspass调用mysql,例如:
1 | sshpass -p topsecret mysql -u root -p username -e 'statement' |
对于PowerShell(
解决方案是覆盖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Function CallMySQL() { # Cache the error action preference $_temp = $ErrorActionPreference $ErrorActionPreference ="Continue" # Capture all output from mysql $output = (&mysql --user=foo --password=bar 2>&1) # Restore the error action preference $ErrorActionPreference = $_temp if ($output -match"ERROR") { throw $output } elseif($output) { " Swallowing $output" } else { " No output" } } |
注意:PowerShell可用于Unix,因此此解决方案是跨平台的。它可以通过一些小的语法修改来适应
警告:有几十种边缘情况下,这是不起作用的,如非英语错误消息或语句返回单词
如果
就我个人而言,我使用脚本包装器来捕获那个错误。以下是代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/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 |
我遇到的问题是在bash脚本的条件中使用输出。
这并不优雅,但在码头环境下,这真的不重要。基本上,所有这些都忽略了不在最后一行的输出。您可以对awk做类似的操作,并更改以返回除第一行以外的所有内容。
这只返回最后一行
1 | mysql -u db_user -pInsecurePassword my_database ... | sed -e '$!d' |
它不会抑制错误,但会确保您可以在bash脚本中使用查询的输出。
另一个解决方案(例如来自脚本):
1 2 | sed -i'' -e"s/password=.*\$/password=$pass/g" ~/.my.cnf mysql -h $host -u $user $db_name -e"$sql_cmd" |
这里的
您可以使用/dev/null执行mysql并禁止警告和错误消息例如:
1 2 3 4 5 |
哪里:
1 2 3 4 5 6 7 8 9 10 11 |
享受!
它对我有用-只是在