Beim Versuch, den folgenden Befehl unter MySQL in Terminal auszuführen:
mysql -u $user -p$password -e "statement"
Die Ausführung funktioniert wie erwartet, es wird jedoch immer eine Warnung ausgegeben:
Warnung: Die Verwendung eines Kennworts in der Befehlszeilenschnittstelle kann unsicher sein.
Ich muss jedoch die obige Anweisung mit einer Umgebungsvariablen ($password
) ausführen, in der mein Kennwort gespeichert ist, da ich den Befehl in Bash-Skript von Terminal aus iterativ ausführen möchte, und ich mag es definitiv nicht, auf eine Eingabeaufforderung zu warten und zwinge mich, mein Passwort 50 oder 100 Mal in einem einzigen Skript einzugeben. Also hier meine Frage:
Kann die Warnung unterdrückt werden? Der Befehl funktioniert wie gesagt, aber das Fenster wird ziemlich unordentlich, wenn ich den Befehl 50 oder 100 Mal durchläuft und den Befehl ausführt.
Soll ich die Warnmeldung befolgen und mein Passwort NICHT in mein Skript schreiben? Wenn dies der Fall ist, muss ich dann jedes Mal mein Passwort eingeben, wenn die Aufforderung mich dazu zwingt?
Das Ausführen von man mysql
hilft nicht und sagt nur
--show-warnings
Falls nach jeder Anweisung Warnungen angezeigt werden, wenn vorhanden. Diese Option gilt für den interaktiven Modus und den Stapelmodus.
und erwähnt nichts darüber, wie man die Funktionalität ausschaltet, wenn mir nichts fehlt.
Ich bin auf OS X 10.9.1 Mavericks und verwende MySQL 5.6 von Homebrew.
Wenn Ihre MySQL-Client-/Server-Version 5.6.x ist, können Sie die WARNING-Meldung mithilfe der Tools mysql_config_editor vermeiden:
mysql_config_editor set --login-path=local --Host=localhost --user=username --password
Dann können Sie in Ihrem Shell-Skript Folgendes verwenden:
mysql --login-path=local -e "statement"
Anstatt:
mysql -u username -p pass -e "statement"
Ich benutze so etwas wie:
mysql --defaults-extra-file=/path/to/config.cnf
oder
mysqldump --defaults-extra-file=/path/to/config.cnf
Wo config.cnf enthält:
[client]
user = whatever
password = whatever
Host = whatever
Dadurch können Sie mehrere Konfigurationsdateien haben - für verschiedene Server/Rollen/Datenbanken. Wenn Sie ~/.my.cnf verwenden, können Sie nur einen Konfigurationssatz haben (es kann jedoch ein nützlicher Satz von Standardeinstellungen sein).
Wenn Sie sich in einer Debian-basierten Distribution befinden und als root ausgeführt werden, könnten Sie das oben stehende überspringen und einfach /etc/mysql/debian.cnf verwenden, um reinzukommen ...:
mysql --defaults-extra-file=/etc/mysql/debian.cnf
Eine bequeme (aber ebenso unsichere) Methode ist die Verwendung von:
MYSQL_PWD=xxxxxxxx mysql -u root -e "statement"
Beachten Sie, dass die offiziellen Dokumente dagegen empfehlen.
Siehe 6.1.2.1 Endbenutzerrichtlinien für die Passwortsicherheit (Mysql-Handbuch für Version 5.6) :
Speichern Ihres Passworts in der Umgebungsvariablen
MYSQL_PWD
Diese Methode zur Angabe Ihres MySQL-Passworts muss als extrem unsicher betrachtet werden und sollte nicht verwendet werden. Einige Versionen von ps enthalten eine Option zum Anzeigen der Umgebung der laufenden Prozesse. Wenn Sie
MYSQL_PWD
einstellen, ist Ihr Kennwort auf einigen Systemen für jeden anderen Benutzer verfügbar, der ps ausführt. Selbst auf Systemen ohne eine solche Version von ps ist es unklug anzunehmen, dass es keine anderen Methoden gibt, mit denen Benutzer Prozessumgebungen untersuchen können.
Wenn Sie ein Kennwort in der Befehlszeile verwenden möchten, habe ich festgestellt, dass dies zum Herausfiltern der jeweiligen Fehlermeldung funktioniert:
mysqlcommand 2>&1 | grep -v "Warning: Using a password"
Im Wesentlichen werden Standardfehler zur Standardausgabe umgeleitet - und mit grep werden alle Zeilen gelöscht, die mit "Warning: Using a password" übereinstimmen.
Auf diese Weise können Sie jede andere Ausgabe einschließlich Fehlern sehen. Ich verwende dies für verschiedene Shell-Skripte usw.
So habe ich mein bash-Skript für meine täglichen mysqldump-Datenbanksicherungen erhalten, um sicherer zu arbeiten. Dies ist eine Erweiterung der großartigen Antwort von Cristian Porta.
Verwenden Sie zuerst mysql_config_editor (wird mit mysql 5.6+ geliefert), um die verschlüsselte Kennwortdatei einzurichten. Angenommen, Ihr Benutzername lautet "db_user". Ausführen von der Shell-Eingabeaufforderung:
mysql_config_editor set --login-path=local --Host=localhost --user=db_user --password
Sie werden aufgefordert, das Kennwort einzugeben. Nach der Eingabe wird der Benutzer/Pass in Ihrem home/system_username/.mylogin.cnf
verschlüsselt gespeichert.
Ändern Sie natürlich "system_username" in Ihren Benutzernamen auf dem Server.
Ändern Sie Ihr Bash-Skript wie folgt:
mysqldump -u db_user -pInsecurePassword my_database | gzip > db_backup.tar.gz
zu diesem:
mysqldump --login-path=local my_database | gzip > db_backup.tar.gz
Keine exponierten Passwörter mehr.
Der einfachste Weg ist
mysql -u root -pMYPASSWORD -e "show databases" 2>/dev/null
Sie können auch den mysql_config_editor in Ihrem Skript ausführen, um das Kennwort bei der Angabe des Anmeldepfads anzugeben
expect -c "
spawn mysql_config_editor set --login-path=$mySqlUser --Host=localhost --user=$mySqlUser --password
expect -nocase \"Enter password:\" {send \"$mySqlPassword\r\"; interact}
"
Dadurch wird eine Expect-Sitzung gestartet, die in Skripts verwendet werden kann, um mit Eingabeaufforderungen zu interagieren
Von 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
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
Um zu sehen, was mysql_config_editor in die Datei .mylogin.cnf geschrieben hat, verwenden Sie den Befehl print:
Shell> mysql_config_editor print --all
[local]
user = localuser
password = *****
Host = localhost
[remote]
user = remoteuser
password = *****
Host = remote.example.com
Der Befehl print zeigt jeden Anmeldepfad als Satz von Zeilen an, die mit einem Gruppenkopf beginnen, der den Namen des Anmeldepfads in eckigen Klammern angibt, gefolgt von den Optionswerten für den Anmeldepfad. Kennwortwerte werden maskiert und erscheinen nicht als Klartext.
Wie in den vorherigen Beispielen gezeigt, kann die Datei .mylogin.cnf mehrere Anmeldepfade enthalten. Auf diese Weise ermöglicht mysql_config_editor die Einrichtung mehrerer "Persönlichkeiten" für die Verbindung mit verschiedenen MySQL-Servern. Jede dieser Optionen kann später mit der Option --login-path beim Aufrufen eines Clientprogramms nach Name ausgewählt werden. Um beispielsweise eine Verbindung zum lokalen Server herzustellen, verwenden Sie diesen Befehl:
Shell> mysql --login-path=local
Verwenden Sie diesen Befehl, um eine Verbindung zum Remote-Server herzustellen:
Shell> mysql --login-path=remote
Eine andere Alternative ist die Verwendung von sshpass, um mysql aufzurufen, z.
sshpass -p topsecret mysql -u root -p username -e 'statement'
Hier ist eine Lösung für Docker in einem Skript/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-database'
Ersetzen Sie [MYSQL_CONTAINER_NAME] und stellen Sie sicher, dass die Umgebungsvariable MYSQL_ROOT_PASSWORD in Ihrem Container festgelegt ist.
Ich hoffe es hilft dir, es könnte mir helfen!
Ein einfaches Workaroud-Skript. Nennen Sie dieses "mysql" und geben Sie es vor "/ usr/bin" ein. Offensichtliche Varianten für andere Befehle oder wenn der Warnungstext unterschiedlich ist.
#!/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
ok, lösung ohne temporäre dateien oder so:
mysql --defaults-extra-file=<(echo $'[client]\npassword='"$password") -u $user -e "statement"
es ähnelt dem, was andere erwähnt haben, aber hier benötigen Sie keine tatsächliche Datei. Dieser Teil des Befehls fälscht die Datei: <(echo ...)
(Beachten Sie, dass in der Mitte von <(
kein Leerzeichen ist.
Persönlich verwende ich einen Skript-Wrapper, um diesen Fehler abzufangen. Hier ist ein Codebeispiel:
#!/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
die beste Lösung ist die Verwendung eines Alias:
alias [yourapp]-mysql="mysql -u root -psomepassword -P3306 -h 127.0.0.1"
fügen Sie beispielsweise Folgendes in Ihr Skript ein:
alias drupal-mysql="mysql -u root -psomepassword -P3306 -h 127.0.0.1"
dann später in Ihrem Skript, um eine Datenbank zu laden:
drupal-mysql database_name < database_dump.sql
um eine Erklärung abzugeben:
drupal-mysql -e "EXEC SOMESTATEMENT;"
Sie können die Standardfehler-STDERR-Ausgabe auch einfach nach/dev/null umleiten
Also mach einfach:
mysql -u $user -p$password -e "statement" 2> /dev/null
Für PowerShell (pwsh
, nicht bash
) war dies eine echte Rube-Goldberg-Lösung ... Mein erster Versuch war, die Aufrufe von mysql
in ein try/catch
- Funktion, aber aufgrund einiger seltsames Verhalten bei der PowerShell-Fehlerbehandlung war dies nicht durchführbar.
Die Lösung bestand darin, den $ErrorActionPreference
- Wert nur so lange zu überschreiben, bis STDERR
und STDOUT
kombiniert, erfasst und für das Wort ERROR
analysiert und bei Bedarf erneut geworfen wurden. Der Grund, warum wir "^mysql.*Warning.*password"
Nicht abfangen und freigeben konnten, ist, dass PowerShell den Fehler als einen Stream behandelt und auslöst, sodass Sie alles erfassen müssen um zu filtern und neu zu werfen. : /
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"
}
}
Hinweis: PowerShell ist für Unix verfügbar, daher ist diese Lösung plattformübergreifend. Es kann mit einigen geringfügigen Syntaxänderungen an bash
angepasst werden.
Warnung: Es gibt Dutzende von Edge-Fällen, in denen dies nicht funktioniert, z. B. nicht-englische Fehlermeldungen oder Anweisungen, die das Wort ERROR
irgendwo in der Ausgabe, aber es war genug, um die Warnung für einen grundlegenden Aufruf von mysql
zu verschlucken, ohne das gesamte Skript zu bombardieren. Hoffentlich finden das andere nützlich.
Es wäre schön, wenn mysql
einfach eine Option hinzufügen würde, um diese Warnung zu unterdrücken.