Подавлять предупреждения с помощью mysql из терминала, но пароль написан на bash script

Когда я попытался запустить следующую команду в MySQL из терминала:

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

Выполнение выполняется так, как ожидалось, но оно всегда выдает предупреждение:

Предупреждение. Использование пароля в интерфейсе командной строки может быть небезопасным.

Однако, я должен выполнить приведенное выше утверждение, используя переменную среды ($password), которая хранит мой пароль, потому что я хочу выполнить команду итеративно в bash script из Terminal, и я определенно не знаю, t нравится идея ожидания появления подсказки и принудительного ввода моего пароля 50 или 100 раз в одном script. Итак, вот мой вопрос:

  • Возможно ли пресечь предупреждение? Команда работает правильно, как я уже сказал, но окно становится довольно беспорядочным, когда я перехожу за циклом и запускаю команду 50 или 100 раз.

  • Должен ли я подчиняться предупреждающему сообщению и НЕ писать свой пароль в моем script? Если это так, то нужно ли мне вводить пароль каждый раз, когда подсказка заставляет меня это делать?

Запуск man mysql не помогает, говоря только

--show-warnings
Объясните предупреждения, которые будут отображаться после каждого утверждения, если они есть. Этот параметр применяется к интерактивному и пакетному режимам.

и ничего не говорит о том, как отключить функциональность, если я чего-то не пропущу.

Я на OS X 10.9.1 Mavericks и использую MySQL 5.6 из homebrew.

Ответ 1

Если ваша версия клиента/сервера MySQL является способом 5.6.xa, чтобы избежать сообщения WARNING, используйте mysql_config_editor инструменты:

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

Затем вы можете использовать в своей оболочке script:

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

Вместо:

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

Ответ 2

Я использую что-то вроде:

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

Это позволяет вам иметь несколько конфигурационных файлов - для разных серверов/ролей/баз данных. Использование ~/.my.cnf позволит вам иметь только одну конфигурацию (хотя это может быть полезный набор значений по умолчанию).

Если вы используете дистрибутив на базе Debian и запускаете его как root, вы можете пропустить вышеуказанное и просто использовать /etc/mysql/debian.cnf, чтобы войти...:

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

Ответ 3

Одним из удобных (но небезопасных) методов является использование:

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

Обратите внимание, что официальные документы рекомендуют против него. См. 6.1.2.1 Руководства конечных пользователей по безопасности паролей (руководство Mysql для версии 5.6):

Сохранение пароля в переменной среды MYSQL_PWD

Этот метод указания пароля MySQL должен считаться крайне небезопасным и не должен использоваться. В некоторых версиях ps имеется опция отображения среды запущенных процессов. В некоторых системах, если вы установите MYSQL_PWD, ваш пароль будет открыт для любого другого пользователя, который запускает ps. Даже в системах без такой версии ps, неразумно предполагать, что нет других методов, с помощью которых пользователи могут просматривать среды процессов.

Ответ 4

Если вы хотите использовать пароль в командной строке, я обнаружил, что это работает для фильтрации конкретного сообщения об ошибке:

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

В основном он перенаправляет стандартную ошибку на стандартный вывод - и с помощью grep удаляются все строки, соответствующие "Предупреждение: использование пароля".

Таким образом вы можете увидеть любой другой вывод, включая ошибки. Я использую это для различных сценариев оболочки и т.д.

Ответ 5

Вот как я получил свой bash script для ежедневных резервных копий базы данных mysqldump для более надежной работы. Это расширение большого ответа Кристиана Порта.

  • Сначала используйте mysql_config_editor (поставляется с mysql 5.6+), чтобы настроить зашифрованный файл паролей. Предположим, что ваше имя пользователя "db_user". Выполняется из командной строки:

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

    Он запрашивает пароль. После того, как вы введете его, пользователь/пропуск сохраняются зашифрованными в home/system_username/.mylogin.cnf

    Конечно, измените имя "system_username" на свое имя пользователя на сервере.

  • Измените bash script следующим образом:

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

    :

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

Больше открытых паролей.

Ответ 6

Самый простой способ -

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

Ответ 7

Вы также можете запустить mysql_config_editor в своем script, чтобы передать пароль при указании пути входа

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

Это запускает сессию ожидания, которая может использоваться в скриптах для взаимодействия с подсказками

См. это сообщение

Ответ 8

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

Команда печати отображает каждый путь входа в систему как набор строк, начинающихся с заголовка группы, указывающего имя пути входа в квадратные скобки, за которым следует значение параметра для пути входа в систему. Значения пароля маскируются и не отображаются как чистый текст.

Как показано в предыдущих примерах, файл .mylogin.cnf может содержать несколько путей входа. Таким образом, mysql_config_editor упрощает настройку нескольких "личностей" для подключения к различным серверам MySQL. Любой из них может быть выбран по имени позже, используя параметр -login-path при вызове клиентской программы. Например, чтобы подключиться к локальному серверу, используйте следующую команду:

shell> mysql --login-path=local

Чтобы подключиться к удаленному серверу, используйте следующую команду:

shell> mysql --login-path=remote

Ответ 9

Из 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

Ответ 10

Другой альтернативой является использование sshpass для вызова mysql, например:

sshpass -p topsecret mysql -u root -p username -e 'statement'

Ответ 11

Простой workaroud script. Назовите этот "mysql" и поместите его на свой путь до "/usr/bin". Очевидные варианты для других команд, или если текст предупреждения отличается.

#!/bin/sh

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

Ответ 12

Вот решение для Docker в сценарии /bin/sh:

docker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo "[клиент]">/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 -c redentials.cnf --all-database'

Замените [MYSQL_CONTAINER_NAME] и убедитесь, что в вашем контейнере установлена переменная среды MYSQL_ROOT_PASSWORD.

Надеюсь, это поможет вам, как это может помочь мне!

Ответ 13

Вы также можете просто перенаправить стандартный вывод ошибки STDERR в /dev/null

Так что просто сделайте:

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

Ответ 14

хорошо, решение без временных файлов или чего-либо еще:

mysql --defaults-extra-file=<(echo $'[client]\npassword='"$password") -u $user -e "statement"

это похоже на то, что упоминали другие, но здесь вам не нужен фактический файл, эта часть команды подделывает файл: <(echo ...) (обратите внимание, что в середине [TG42 нет места) ]

Ответ 15

Лично я использую оболочку script, чтобы поймать эту ошибку. Вот пример кода:

#!/bin/bash

#echo [email protected] | cat >> /home/mysqldump.log 2>/dev/null
ERR_FILE=/tmp/tmp_mdump.err

# Execute dumper
/usr/bin/mysqldump [email protected] 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

Ответ 16

Для PowerShell (pwsh, а не bash) это было решение rube-goldberg... Моя первая попытка заключалась в том, чтобы обернуть вызовы mysql в функцию try/catch, но из-за некоторого странного поведения в обработке ошибок PowerShell это было не жизнеспособен

Решение состояло в том, чтобы переопределить $ErrorActionPreference достаточно долго, чтобы объединить и STDERR и STDOUT проанализировать слово ERROR и перезапустить при необходимости. Причина, по которой мы не смогли перехватить и освободить "^mysql.*Warning.*password" заключается в том, что PowerShell обрабатывает и выдает ошибку как один поток, поэтому вы должны захватить ее все для фильтрации и повторного выброса. :/

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, поэтому данное решение является кроссплатформенным. Его можно адаптировать для bash с небольшими модификациями синтаксиса.

Предупреждение: существуют десятки крайних случаев, когда это не сработает, таких как неанглийские сообщения об ошибках или операторы, которые возвращают слово ERROR любом месте вывода, но этого было достаточно, чтобы усвоить предупреждение для базового вызова mysql без бомбардировки из всего сценария. Надеюсь, другие найдут это полезным.

Было бы хорошо, если бы mysql просто добавил опцию для подавления этого предупреждения.

Ответ 17

лучшее решение - использовать псевдоним:

alias [yourapp]-mysql="mysql -u root -psomepassword -P3306 -h 127.0.0.1"

Например, поместите это в ваш скрипт:

alias drupal-mysql="mysql -u root -psomepassword -P3306 -h 127.0.0.1"

затем в вашем скрипте для загрузки базы данных:

drupal-mysql database_name < database_dump.sql

запустить выражение:

drupal-mysql -e "EXEC SOMESTATEMENT;"

Ответ 18

Самый простой способ:

mysql -u root -p YOUR_DATABASE

Введите это, и вам нужно будет ввести свой пароль.

Примечание: Да, без точки с запятой.

Ответ 19

Другое решение (например, от script):

 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

Ответ 20

Проблема, с которой я столкнулась, заключалась в использовании вывода в условном выражении в bash script.

Это не изящно, но в докере env это действительно не имеет значения. В основном все это игнорирует вывод, который не находится в последней строке. Вы можете сделать подобное с awk и изменить, чтобы вернуть все, кроме первой строки и т.д.

Это возвращает только последнюю строку

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

Он не будет подавлять ошибку, но он будет уверен, что вы можете использовать вывод запроса в bash script.

Ответ 21

Вы можете выполнить mySQL и подавить предупреждения и сообщения об ошибках, используя /dev/null например:

# 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

наслаждайтесь!

Ответ 22

Это сработало для меня - Просто добавьте 2> null после $(mysql_command), и он будет подавлять только сообщения об ошибках и предупреждения.