Suprime los mensajes de advertencia usando mysql desde Terminal, pero la contraseña está escrita en script bash

Cuando intenté ejecutar el siguiente comando en MySQL desde Terminal:

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

La ejecución funciona como se espera, pero siempre emite una advertencia:

Advertencia: Usar una contraseña en la interfaz de línea de comando puede ser inseguro.

Sin embargo, tengo que realizar la statement anterior usando una variable de entorno ( $password ) que almacena mi contraseña, porque quiero ejecutar el comando de forma iterativa en el script bash desde Terminal, y definitivamente no me gusta la idea de esperar un mensaje apareciendo y forzándome a ingresar mi contraseña 50 o 100 veces en una sola secuencia de comandos. Así que aquí está mi pregunta:

  • ¿Es factible suprimir la advertencia? El comando funciona correctamente como dije, pero la ventana se vuelve bastante desordenada cuando hago un bucle y ejecuto el comando 50 o 100 veces.

  • ¿Debo obedecer el mensaje de advertencia y NO escribir mi contraseña en mi script? Si ese es el caso, ¿debo escribir mi contraseña cada vez que el aviso me obligue a hacerlo?

Running man mysql no ayuda, diciendo solo

--show-warnings
Causa advertencias que se muestran después de cada statement, si las hay. Esta opción se aplica al modo interactivo y por lotes.

y no menciona nada sobre cómo desactivar la funcionalidad, si no me falta algo.

Estoy en OS X 10.9.1 Mavericks y uso MySQL 5.6 desde homebrew.

Si su versión de cliente / servidor MySQL es una forma 5.6.xa de evitar el mensaje de ADVERTENCIA están utilizando las herramientas mysql_config_editor :

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

Entonces puedes usar en tu script de shell:

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

En lugar de:

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

Yo uso algo como:

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

o

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

Donde config.cnf contiene:

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

Esto le permite tener múltiples archivos de configuración para diferentes servidores / roles / bases de datos. Usar ~ / .my.cnf solo le permitirá tener un conjunto de configuraciones (aunque puede ser un conjunto útil de valores predeterminados).

Si está en una distribución basada en Debian y se ejecuta como root, puede omitir lo anterior y simplemente usar /etc/mysql/debian.cnf para entrar …:

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

Un método que es conveniente (pero igualmente inseguro) es usar:

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

Tenga en cuenta que los documentos oficiales lo recomiendan.
Consulte 6.1.2.1 Pautas para el usuario final para la seguridad de contraseñas (Manual de Mysql para la Versión 5.6) :

Almacenar su contraseña en la variable de entorno MYSQL_PWD

Este método de especificar su contraseña MySQL debe considerarse extremadamente inseguro y no debe utilizarse. Algunas versiones de ps incluyen una opción para mostrar el entorno de los procesos en ejecución. En algunos sistemas, si configura MYSQL_PWD , su contraseña MYSQL_PWD expuesta a cualquier otro usuario que ejecute ps . Incluso en sistemas sin esa versión de ps , no es prudente suponer que no hay otros métodos por los cuales los usuarios puedan examinar entornos de procesos.

Si desea utilizar una contraseña en la línea de comando, he encontrado que esto funciona para filtrar el mensaje de error específico:

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

Básicamente redirige el error estándar a la salida estándar y usa grep para eliminar todas las líneas que coincidan con “Advertencia: utilizando una contraseña”.

De esta forma, puede ver cualquier otra salida, incluidos los errores. Lo uso para varios scripts de shell, etc.

Así es como obtuve mi script bash para que mis copias de seguridad diarias de la base de datos mysqldump funcionen de forma más segura. Esta es una expansión de la gran respuesta de Cristian Porta.

  1. Primero use mysql_config_editor (viene con mysql 5.6+) para configurar el archivo de contraseña cifrada. Supongamos que su nombre de usuario es “db_user”. Ejecutando desde el prompt de shell:

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

    Solicita la contraseña. Una vez que lo ingresa, el usuario / pase se guarda cifrado en su home/system_username/.mylogin.cnf

    Por supuesto, cambie “system_username” a su nombre de usuario en el servidor.

  2. Cambie su script bash de esto:

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

    a esto:

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

No más contraseñas expuestas.

La manera más fácil es

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

También puede ejecutar mysql_config_editor en su secuencia de comandos para pasar la contraseña al especificar la ruta de inicio de sesión

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

Esto inicia una sesión de espera que se puede usar en scripts para interactuar con las solicitudes

Ver esta publicación

Desde 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 

Otra alternativa es usar sshpass para invocar a mysql, por ejemplo:

 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 

Para ver lo que mysql_config_editor escribió en el archivo .mylogin.cnf, use el comando print:

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

El comando de impresión muestra cada ruta de inicio de sesión como un conjunto de líneas que comienza con un encabezado de grupo que indica el nombre de la ruta de acceso entre corchetes, seguido de los valores de opción para la ruta de acceso. Los valores de contraseña están enmascarados y no aparecen como texto claro.

Como se muestra en los ejemplos anteriores, el archivo .mylogin.cnf puede contener varias rutas de inicio de sesión. De esta manera, mysql_config_editor hace que sea fácil configurar múltiples “personalidades” para conectarse a diferentes servidores MySQL. Cualquiera de estos se puede seleccionar por nombre más tarde utilizando la opción –login-path cuando invoca un progtwig cliente. Por ejemplo, para conectarse al servidor local, use este comando:

 shell> mysql --login-path=local 

Para conectarse al servidor remoto, use este comando:

 shell> mysql --login-path=remote 

Aquí hay una solución para Docker en un script / bin / sh:

docker exec [MYSQL_CONTAINER_NAME] sh -c ‘exec echo “[cliente]”> /root/mysql-credentials.cnf’

docker exec [MYSQL_CONTAINER_NAME] sh -c ‘exec echo “usuario = root” >> /root/mysql-credentials.cnf’

docker exec [MYSQL_CONTAINER_NAME] sh -c ‘exec echo “contraseña = $ MYSQL_ROOT_PASSWORD” >> /root/mysql-credentials.cnf’

docker exec [MYSQL_CONTAINER_NAME] sh -c ‘exec mysqldump –defaults-archivo-extra = / root / mysql-credentials.cnf –all-databases’

Reemplace [MYSQL_CONTAINER_NAME] y asegúrese de que la variable de entorno MYSQL_ROOT_PASSWORD esté configurada en su contenedor.

Espero que te ayude como si pudiera ayudarme.

Personalmente, uso script wrapper para detectar ese error. Aquí hay una muestra de código:

 #!/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 

Para PowerShell ( pwsh , no bash ), esta fue toda una solución de rube-goldberg … Mi primer bash fue envolver las llamadas a mysql en una función try/catch , pero debido a un comportamiento extraño en el manejo de errores de PowerShell , esto no fue posible. es viable.

La solución fue anular $ErrorActionPreference tiempo suficiente para combinar y capturar STDERR y STDOUT y analizar la palabra ERROR y volver a lanzar según sea necesario. La razón por la que no pudimos detectar y liberar en "^mysql.*Warning.*password" es porque PowerShell maneja y genera el error como una secuencia, por lo que debe capturarlo todo para filtrar y volver a lanzar. : /

 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" } } 

Nota: PowerShell está disponible para Unix, por lo que esta solución es multiplataforma. Se puede adaptar para bash con algunas modificaciones menores de syntax.

Advertencia: hay docenas de casos extremos en los que esto no funcionará, como mensajes de error no ingleses o declaraciones que devuelvan la palabra ERROR en cualquier lugar de la salida, pero fue suficiente para tragarse la advertencia de una llamada básica a mysql sin bombardeo la secuencia de comandos completa Ojalá otros lo encuentren útil.

Sería bueno si mysql simplemente agregara una opción para suprimir esta advertencia.

También puede redireccionar el error STDERR estándar a / dev / null

Así que hazlo:

mysql -u $user -p$password -e "statement" 2> /dev/null

Otra solución (de un script, por ejemplo):

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

La opción -i'' está aquí para compatibilidad con Mac OS X. Los sistemas operativos UNIX estándar pueden usar -i directa

El problema que tuve fue usar la salida en un condicional en un script bash.

Esto no es elegante, pero en un docker env esto realmente no debería importar. Básicamente todo lo que hace es ignorar el resultado que no está en la última línea. Puede hacer lo mismo con awk, y cambiar para devolver todo menos la primera línea, etc.

Esto solo devuelve la última línea

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

No suprimirá el error, pero se asegurará de que pueda usar el resultado de una consulta en un script bash.

Puede ejecutar mySQL y suprimir los mensajes de advertencia y error usando / dev / null por ejemplo:

 # 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 

Dónde:

 ${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 

¡disfrutar!

Un simple script workaroud. Nombra este “mysql” y ponlo en tu camino antes de “/ usr / bin”. Variantes obvias para otros comandos, o si el texto de advertencia es diferente.

 #!/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 

Me funcionó: acaba de agregar 2> null después de $(mysql_command) , y solo suprimirá los mensajes de Errores y Advertencia.