2017-10-10 389 views
2

我有以下bash腳本來升級我的數據庫模式。腳本從命令行讀取主機名和數據庫密碼。具有特殊字符的Mysql命令行密碼不起作用

的問題是在這裏,如果密碼是字母數字 e.g 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

這種情況的原因是您正在使用shell GLOB(通配符)字符的密碼,並在巴什(或者在Linux上一般)通配符被shell擴展。

最安全和最可靠的解決方案是不使用shell通配符或shell中由密碼解釋的其他字符。你也應該避免空格。還有很多其他的角色。

這裏是那些你應該避免:

「'$,[] * {}〜#%\ <> |

這裏是那些通常是安全的用途:

:; @/+ -

!爲確保密碼安全,請延長密碼。舉個例子:

沃頓3amvv7l1wz1192sjqhym

這符合老式的密碼複雜性規則,因爲上,下,數字和特殊字符都在第4位,是隨機產生的餘數,但避免了任何有問題的字符。

但是,如果您必須使用它們,您可以用單引號引用密碼參數 - 儘管如果密碼包含單引號,仍會遇到麻煩!

+0

感謝您的回答。但我需要讓腳本接受這些角色,因爲有些用戶已經在使用這些角色的密碼。 – myprogram

0

變量最適用於數據,而不是代碼。當你需要擴展的某些部分時(例如,你希望命令行在你想要的標記上被分割),但是不想要所有其他的效果,這些變量層很難保護擴展。解決方案是不將代碼存儲在字符串中。相反,使用類似功能:

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

,那麼你可以像

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

有額外的參數,它雖然也將是最好不要使用大寫爲您的變量。這樣做使得它可以與環境變量相沖突並意外改變你不想改變的東西(因爲意外重置的人數可以證明)。