ターミナル内からmysqlを使用して警告メッセージを抑制しますが、パスワードはbashスクリプトで記述されます


273

ターミナル内からMySQLで次のコマンドを実行しようとしたとき:

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

実行は期待どおりに機能しますが、常に警告が表示されます。

警告:コマンドラインインターフェイスでパスワードを使用すると、安全でない場合があります。

ただし、$passwordターミナル内からbashスクリプトでコマンドを繰り返し実行したいので、パスワードを格納する環境変数()を使用して上記のステートメントを実行する必要があります。 1つのスクリプトでパスワードを50回または100回入力するように強制します。だから私の質問です:

  • 警告を抑制することは可能ですか?私が述べたようにコマンドは適切に機能しますが、ループしてコマンドを50回または100回実行すると、ウィンドウがかなり乱雑になります。

  • 警告メッセージに従い、スクリプトにパスワードを書き込まないでください。その場合、プロンプトで強制されるたびにパスワードを入力する必要がありますか?

ランニングman mysqlは役に立たない、ただ言うだけ

--show-warnings
警告がある場合、各ステートメントの後に警告を表示します。このオプションは、インタラクティブモードとバッチモードに適用されます。

そして、私が何かを逃していない場合、機能をオフにする方法については何も言及していません。

私はOS X 10.9.1 Mavericksを使用していて、自作のMySQL 5.6を使用しています。


14
推奨される方法は、オプションファイルにパスワードを保存することです(smthのよう[client] password=my_password~/.my.cnf)。確かにそれはあまりにもいくつかのセキュリティの意味を持っていますが、少なくともそれはへのアクセスはありません誰も実行することができps、あなたはファイルのパーミッションとそれを制御することができます。
アントン

4
mysql -u root password root -e "statement" > /dev/null

ところで、Pythonのようなものを使用することもできますpexcept。端末の挿入を行うことができ、コマンドが与えるフィードバックも処理できます。この方法では、その冗長な出力をスキップして、必要な実際の出力を

6
推奨される方法では、IMOは正しいことを行うものにペナルティを課し、間違ったことを行うものを保護します。パスワードがスクリプトファイル内に保存されている場合、psやログには表示されません。これが正しい方法です。ファイルを外部ファイルに置くことは、パスワードをcronするものを助けますが、それは最初から悪いことです。それまでの間、何年も実行されてきたスクリプトは失敗し、この警告がstderrで表示されるため、スクリプトを変更する必要があります。
Nestor Urquiza

2
明らかにパスワードを保存しないwhcih推奨方法については、に詳述されているdev.mysql.com/doc/refman/5.6/en/mysql-config-editor.html
アンソニー

回答:


250

MySQLクライアント/サーバーのバージョンが5.6.xaの場合、警告メッセージを回避する方法として、mysql_config_editorツールを使用します。

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

次に、シェルスクリプトで使用できます。

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

の代わりに:

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

28
--login-pathは他のすべての議論の前にある必要があることを覚えておいてください。mysqldump --tables --login-path=localエラーを取得しようとしましたunknown variable 'login-path=local'
Tulio 2014年

mysqlコマンドラインクライアントは、デフォルトで「クライアント」ログインパスの下を調べます。小さな変更を加えることで、「mysql -e 'statement'」への指示を簡略化できます。
モーガン・トッカー、2015

2
これは、シェルファイルを直接実行する場合は正常に機能しますが、crontabから呼び出される場合は機能しません
Nabeel Arshad

1
@NabeelArshadこれは、crontabでユーザーの「ホーム」が設定されていないため(一般的にENV変数)、クライアントが正しい〜/ .mylogin.cnfを見つけられないためだと思います
Cristian Porta

1
@NamGVU、確かではありませんが、このソリューションには暗号化されたパスワードが格納されていると思います。
zhekaus

209

私は次のようなものを使用します:

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を使用すると、1つの設定セットのみが許可されます(デフォルトの有用なセットである場合もあります)。

Debianベースのディストリビューションを使用していて、ルートとして実行している場合は、上記をスキップして/etc/mysql/debian.cnfを使用するだけで...にアクセスできます。

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


12
注:--defaults-extra-file最初のオプションである必要がありますmysqldump: unknown variable 'defaults-extra-file。そうでない場合、mysqlはで不平を言います。
pevik 2014

4
受け入れられた答えの素晴らしい選択肢。絶対にMYSQL_PWD変数を設定しないでください...
DudeOnRock 2014年

1
5.6より前のバージョンには間違いなく良いオプションです。そうでなければ、私は受け入れられた答えで行きます。
dkniffin 2014年

21
一時的な.cnfファイルを作成する代わりに、これをBashで実行することもできますmysql --defaults-extra-file=<(printf "[client]\nuser = %s\npassword = %s" "$user" "$pwd") -e "statement"printfはBashによって直接実行されるため、には表示されませんps
Dave James Miller、

3
後者では〜/ .my.cnfの設定が優先されるため、--defaults-fileではなくを使用する必要があり--defaults-extra-fileました。
Roger Dueck 16

186

便利な(ただし、同様に安全ではない)方法の1つは、次のものを使用することです。

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

公式ドキュメントはそれを推奨していないことに注意してください。6.1.2.1パスワードセキュリティのエンドユーザーガイドライン(バージョン5.6のMySQLマニュアル)を
参照してください。

パスワードをMYSQL_PWD環境変数に保存する

MySQLパスワードを指定するこの方法は、非常に安全でないと見なす必要があり、使用しないでください。psの一部のバージョンには、実行中のプロセスの環境を表示するオプションが含まれています。一部のシステムでは、を設定するとMYSQL_PWDpsを実行する他のユーザーにパスワードが公開されます。このようなバージョンのpsがないシステムでも、ユーザーがプロセス環境を調査できる他の方法がないと想定するのは賢明ではありません。


6
これは私のbashスクリプトは動作しません:Access denied for user 'root'@'localhost' (using password: NO)
rubo77

24
スクリプトでは、する必要がありexport MYSQL_PWD=whateverます。
Riot

2
私のクエリは非常に高速なので、このオプションを選択しました。次に、クエリを実行した後、それを偽の値に設定しました。
TimH-Codidact

11
このスクリプトでは、実行する必要はありません。exportただ、すべて1行上に置き、:MYSQL_PWD=xxxxxxxx mysql -u root -e "statement"
JD

1
@JD:私の場合、Ubuntu 16.04とMySQL 5.7.21で動作します。
mivk 2018

70

コマンドラインでパスワードを使用したい場合、これが特定のエラーメッセージを除外するために機能することがわかりました。

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

これは基本的に標準エラーを標準出力にリダイレクトし、grepを使用して「警告:パスワードの使用」に一致するすべての行をドロップします。

このようにして、エラーを含む他の出力を確認できます。これをさまざまなシェルスクリプトなどに使用します。


これは、CapistranoデプロイメントのRakeタスクの作成など、他のタスクで呼び出されるワンライナータスクで使用するための優れたソリューションです。
JakeGould 2016

2
そのメッセージをミュートするための優れたシンプルな方法で、MySQLのセットアップで何も変更する必要はありません。
ajaaskel

SQLのリダイレクトがすでにある場合、これをmysqldumpでどのように使用しますか?
MacroMan、2018年

1
これは、ここにある他のソリューションと比較して本当に悪いソリューションです。テキストが変更された場合、それ以降のバージョンのMySQLでは失敗する可能性があり、別のロケールでも機能しない可能性があります。
yktoo 2018

42

これが、毎日のmysqldumpデータベースバックアップ用のbashスクリプトをより安全に機能させる方法です。これはクリスチャン・ポルタの素晴らしい答えの拡張です。

  1. 最初に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」をサーバー上のユーザー名に変更します。

  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

これ以上公開されたパスワードはありません。


10

最も簡単な方法は

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

43
問題は、これがスクリプト内の正当なエラーも抑制することです。
man910 2014

4
また、ログファイル2> /var/log/myscript.logを作成して、そのエラーを記録することもできます。
Skamasle 2014

1
2>/dev/null | grep -v "mysql: [Warning] Using a password on the command line interface can be insecure."問題の警告のみを
抑制

10

ログインパスを指定するときに、スクリプトで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}
"

これにより、スクリプトでプロンプトと対話するために使用できるExpectセッションが開始されます

この投稿を見る


それは本当に「>」が存在することを意味していますか?
David Goodwin

はい '>'は、mysql_config_editorがstdoutから入力を取得できるようにするためのものです。stdoutからmysql_config_editorに渡されるのは、このユーザーに「>」なしで設定してもらいたいパスワードです。その後、echoコマンドが解析され、echoコマンドの後のすべてが表示されます
phylanx

つまり、パイプ演算子「|」を使用するということですか?少なくとも、* nixとDOSでは、「>」はSTDOUTをキャプチャし、現在の作業ディレクトリの「mysql_config_editor」というファイルに書き込みます。
Jay Dansand 14

はい、正解です。元の回答を編集しました
phylanx

7

わかりました、一時ファイルまたは何もないソリューション:

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

それは他の人が言ったことに似ていますが、ここでは実際のファイルは必要ありません、コマンドのこの部分はファイルを偽装します<(echo ...) (中央にスペースがないことに注意してください)<(


既にパスワードエントリのある.my.cnfファイルがある場合、これは機能しません~/.
santiago arizti

5
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コマンドは、各ログインパスを、角括弧で囲まれたログインパス名を示すグループヘッダーで始まり、その後にログインパスのオプション値が続く一連の行として表示します。パスワード値はマスクされ、クリアテキストとして表示されません。

前の例で示したように、.mylogin.cnfファイルには複数のログインパスを含めることができます。このように、mysql_config_editorを使用すると、異なるMySQLサーバーに接続するための複数の「パーソナリティ」を簡単に設定できます。これらはいずれも、後でクライアントプログラムを呼び出すときに--login-pathオプションを使用して名前で選択できます。たとえば、ローカルサーバーに接続するには、次のコマンドを使用します。

shell> mysql --login-path=local

リモートサーバーに接続するには、次のコマンドを使用します。

shell> mysql --login-path=remote

www-dataユーザーとしてmysqldumpコマンドを実行したい場合はどうなりますか?www-dataにホームディレクトリがありません... www-dataユーザー用にmysql_config_editorを設定するにはどうすればよいですか?
lewis4u

5

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

3

もう1つの方法は、sshpassを使用してmysqlを呼び出すことです。例:

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

機能しているようですが、コマンドラインから「username」を削除する必要がありますね。
e2-e4 2017年

3

単純なworkaroudスクリプト。これに「mysql」という名前を付け、パスの「/ usr / bin」の前に置きます。他のコマンドの明らかな変形、または警告テキストが異なる場合。

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

3
この回答は少し複雑ですが、明確に間違っていないか、コメントがなくて型破りな回答になっているのを見るのはとても面倒なので、私はそれを賛成しました!Davidが他の質問に答えていないのも不思議ではありません。彼は飛び込んで新しい解決策を手助けしようとしましたが、その理由は説明されずに非難されました!コメントを残さないFU匿名の投票者!
ジェレミー・デイビス

3
+1ジェレミー・デイビスに同意する。これは複雑ですが、他に選択肢がない場合は、これで十分です。今までで最も愚かな考えでなければならない警告をオフにするのとは異なり、それは間違いなく間違いではありません!
ベンマッキンタイア

1
@JeremyDavisはい、これは、主に私が作品を見せたかったため、入り組んでいました。括弧なしで実行することもできますが、あまり明確ではなかったかもしれません。これは、すべてのスタック交換で初めての非読み取りアクティビティでもありました...その後、長い間触れていませんでした。あなたのコメントは間違いなく高く評価されました。
David G.

@DavidG。-私のコメントがあなたにとって価値があったことを嬉しく思います。また、あなたが戻ってきて、あなたの答えがポジティブな領域にあることを見るのも素晴らしいことです。個人的には、コメントせずに下向き投票することは許されないと思います。
Jeremy Davis

そうは言っても、あなたの答えを振り返ってみると、一時的な問題(単一のスクリプトで使用するためのエラーメッセージを抑制する)に対する永続的な解決策(本質的にはmysqlをラップする)が最善の方法であるとは確信していません。IMOがmysqlをスクリプト内の関数にラップする(ここでのメソッドの使用は問題ありません)のが優れたアプローチです。私の2c ... :)
Jeremy Davis

3

以下は、スクリプト/ bin / sh内のDockerのソリューションです。

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が設定されていることを確認します。

それが私を助けることができるようにそれがあなたを助けることを願っています!


悪くない。私はリターンで1つの呼び出しをdocker exec [MYSQL_CONTAINER_NAME] sh -c 'exec echo "[client] [RETURN HERE] password=pa55" > /root/defaults'使用しました。たとえば、--defaults-fileそれを使用するとすでにルートも取得します。
マシューウィルコクソン

3

標準エラーSTDERR出力を/ dev / nullにリダイレクトすることもできます

だからちょうどしてください:

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


7
それは合法的なエラーが困難キャッチになるだろうので、私はこのように、この方法を避けるだろう
ウラジミールHraban

1

個人的には、スクリプトラッパーを使用してそのエラーをキャッチしています。ここにコードサンプルがあります:

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

1

PowerShell用(pwsh、ではないbash)、これは私の最初の試みはへの呼び出しをラップすることだった...かなりルーブ・ゴールドバーグ・ソリューションだったmysqltry/catch機能が、何らかのにPowerShellのエラー処理で奇妙な行動、これは実行可能ではなかったです。

解決策は、単語$ErrorActionPreferenceを結合してキャプチャSTDERRSTDOUT、解析して、ERROR必要に応じて再スローするのに十分な時間をオーバーライドすることでした。キャッチして解放できなかった理由"^mysql.*Warning.*password"は、PowerShellがエラーを1つのストリームとして処理して発生させるため、フィルター処理して再スローするためにすべてキャプチャする必要があるためです。:/

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この警告を抑制するオプションを追加するだけでいいのですが。


1

Rundeckを使用してタスクをスケジュールする場合、またはmylogin.cnfファイルを要求する他のプラットフォームを使用している場合、SQL呼び出しを続行する前に、次のシェルコードを使用してファイルの新しい場所を提供できました。

if test -f "$CUSTOM_MY_LOGINS_FILE_PATH"; then
   chmod 600 $CUSTOM_MY_LOGINS_FILE_PATH
   export MYSQL_TEST_LOGIN_FILE="$CUSTOM_MY_LOGINS_FILE_PATH"
fi

...

result=$(mysql --login-path=production -NBA -D $schema -e "$query")

どこにMYSQL_TEST_LOGIN_FILEデフォルトのものとは異なるファイル・パスに設定することができ、環境変数です。

これは、フォークされたプロセスで実行していて、ファイルを$HOMEディレクトリに移動またはコピーできない場合に特に便利です。

こちらのドキュメントをご覧ください。


0

最善の解決策はエイリアスを使用することです:

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

その後、aliaasをUNALIAS:
ニール・デイヴィス

ちなみに、スクリプト内の関数内でmysqlを呼び出す場合は、エイリアスを使用できません。
user3616725

0

ヘルパーを定義します。

remove-warning () {
    grep -v 'mysql: [Warning] Using a password on the command line interface can be insecure.'
}

これを使って:

mysql -u $user -p$password -e "statement" 2>&1 | remove-warning

タチャーン!あなたのコードはきれいで読みやすいです

(bashでテスト済み)


-1

別の解決策(たとえば、スクリプトから):

 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のOSとの互換性のためにここにあります-i


1
パスワードはまだ「sed」のコマンドラインにあるため、たとえ短時間であっても、プロセスリストには表示されたままです。
アンソニー

-1

私が抱えていた問題は、bashスクリプトの条件付きで出力を使用することでした。

これはエレガントではありませんが、Dockerの環境ではこれは問題になりません。基本的にこれは、最終行にない出力を無視するだけです。awkでも同様のことができ、最初の行以外すべてを返すように変更できます。

これは最後の行のみを返します

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

エラーは抑制されませんが、bashスクリプトでクエリの出力を使用できるようになります。


-1

最も簡単な方法:

mysql -u root -p YOUR_DATABASE

これを入力すると、パスワードを入力する必要があります。

注:はい、セミコロンなし。


-3

たとえば/ 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

楽しい!


1
パスワードの警告だけでなく、すべてのエラーメッセージが抑制されることに注意してください。
Simon East

-3

それは私のために働きました-の2> null後に追加されました$(mysql_command)、そしてそれはエラーと警告メッセージだけを抑制します。


1
また、他の問題が発生したときにレポートが届かないことも意味します。
アンソニー

また、あなたはおそらく望んでいました2>/dev/null。を使用2> nullすると、出力は現在のディレクトリの「null」というファイルに入れられます。
thelogix 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.