2017-10-10 13 views
2

データベーススキーマをアップグレードするためのbashスクリプトは、次のとおりです。スクリプトは、コマンドラインからホスト名とデータベースパスワードを読み取ります。特殊文字を使用したMysqlのコマンドラインパスワードが機能しない

問題は、パスワードが英数字例えばr00t、スクリプトの作品であればということここにあります。パスワードに特殊文字(、pa ** w0rdなど)が含まれている場合、スクリプトは機能せず、そのまま終了します。これで私を助けてください。ありがとう。

#!/bin/bash 

echo "Enter hostname." 
read -p "Hostname [localhost]: " DB_HOST 
DB_HOST=${DB_HOST:-localhost} 

echo "Enter MySQL root password" 
DB_PASS= 
while [[ $DB_PASS = "" ]]; do 
    read -sp "Password: " DB_PASS 
done 

MYSQL="mysql --force --connect-timeout=90 --host=$DB_HOST -u root --password=${DB_PASS}" 

# Apply schema updates. My DBName is "mydb" 
# Upgrade schema file is stored in "mysql" folder 

$MYSQL mydb -e exit > /dev/null 2>&1 && $MYSQL mydb < "../mysql/upgrade_schema_v.2.1.sql" 
+0

パスワードが変更されたことを知っている文字のみを使用するように変更します。セキュリティのため、パスワードを長くする必要があります。 – Ben

+0

この問題は、実際には文字列として実行するコマンドを格納しようとしているようです。 http://mywiki.wooledge.org/BashFAQ/050を参照してください。コードの繰り返しを避けるには、正しく引用符で囲まれていない文字列の代わりに関数を使用する方がよいでしょう。 –

答えて

1

パスワードを一重引用符で囲んでみてください。

それはpa**w0rdだ場合は、パスワードでシェルグロブ(ワイルドカード)文字を使用しているので、これが発生している'pa**w0rd'

+0

しかし、私はコマンドラインからパスワードを読んでいます、私はそれを引用する方法を教えてください?お返事ありがとう – myprogram

2

使用し、バッシュで(またはLinux上で一般)ワイルドカードはシェルによって展開されます。

最も安全で最も信頼性の高い解決策は、シェルのワイルドカード文字やパスワードでシェルが解釈する他の文字を使用しないことです。スペースも避ける必要があります。他にもたくさんのキャラクターがあります。ここで

あなたは避けなければならないものです。

" '$、[] * {}〜#%\ <> |ここ

は、それが通常に安全であるものがありますか?使用:

:; @、/ + -

。!パスワードが安全であることを確認するには、パスワードをもっと長くしてください。

、上下数字と特殊文字が最初の4つであるので、これは、昔ながらのパスワードの複雑性ルールを満たし

3amvv7l1wz1192sjqhymが、残りはランダムに生成されたKの@しかしないようにします例として問題のある文字。

ただし、パスワードパラメータを使用する必要がある場合は、一重引用符でパスワードパラメータを引用できますが、パスワードに一重引用符が含まれていても問題は発生しません。

+0

ありがとうございます。しかし、すでにそれらの文字でパスワードを使用している顧客がいるため、これらの文字を受け入れるスクリプトを作成する必要があります。 – myprogram

0

変数はコードではなくデータに最適です。変数のレイヤーは、展開の一部をしたいとき(つまり、あなたが望むトークンでコマンドラインを単語に分割したいとき)には、拡張を保護するのが難しくなりますが、他のすべての効果は望んでいません。解決策は、コードを文字列に格納しないことです。またあなたの変数の大文字を使用しない方が良いでしょうけれども、あなたは

do_mysql "$DB_HOST" "$DB_PASS" -e exit > /dev/null && do_mysql "$DB_HOST" "$DB_PASS" < "../mysql/upgrade_schema_v.2.1.sql" 

のような余分な引数でそれを実行することができます

do_mysql() { 
    host="$1" 
    pass="$2" 
    mysql --force --connect-timeout=90 --host="$host" -u root --password="$pass" "[email protected]" 
} 

:代わりに、のような関数を使用します。そうすることで、環境変数と衝突したり、誤って変更したくないものを誤って変更したりすることがあります(誤ってPATHをリセットする人の数が証明できる)。

関連する問題