Bash
將密碼 (cat) 傳遞給 sed 以替換配置值
我有一個名為的配置文件
.env
,其中包含:
DB_PASSWORD={password}
我們有一個MySQL
/root/.mysql/db00.yml.db
root 帳戶的密碼。我正在嘗試將其導入sed
以下內容:cat /root/.mysql/db00.yml.db | sed -i -e "s/DB_PASSWORD=/DB_PASSWORD=(.*)/g" .env
沒有任何運氣,嘗試了一些變化,例如:
sed -i "s/DB_PASSWORD=/DB_PASSWORD=$(cat /root/.mysql/db00.yml.db)" .env
mysqlpwd=$(cat /root/.mysql/db00.yml.db) # Use the variable in sed -i sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/g" .env
這會產生錯誤:
root@linuxbox:/var/www/www.example.com# mysqlpwd=$(cat /root/.mysql/db00.yml.db) root@linuxbox:/var/www/www.example.com# sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/g" .env sed: -e expression #1, char 33: unknown option to `s'
更新:
不執行它
/g
也會失敗:root@linuxbox:/var/www/www.example.com# echo $mysqlpwd Rjcr/Sn+s/a2QbGx root@linuxbox:/var/www/www.example.com# cat .env | grep DB_PASSWORD DB_PASSWORD=(.*)() root@linuxbox:/var/www/www.example.com# sed -i "s/DB_PASSWORD=/DB_PASSWORD=$mysqlpwd/" .env sed: -e expression #1, char 33: unknown option to `s'
這些方法似乎都不起作用。
我正在跑步
sed 4.7
,即:root@linuxbox:/var/www/www.example.com# sed --version sed (GNU sed) 4.7
嘗試為 sed 使用不同的分隔符…根據您的實際密碼(例如,如果它包含*|或&或\1*),仍然存在失敗的風險。
sed -i "s|DB_PASSWORD=|DB_PASSWORD=$mysqlpwd|" .env
就其本質而言,必須允許密碼包含任何可由鍵盤可靠生成的字元。這意味著密碼可以很容易地包含有效
sed
程式碼或字元串,這些程式碼或字元串在註入sed
編輯腳本時會破壞該腳本,寫入系統上的任意文件,或者使用 GNUsed
執行任意命令(當您以根,你似乎是)。
sed
當您需要使用使用者提供的數據時不要使用,除非您確切知道如何清理它。我個人會避免sed
任何需要我對sed
錶達式進行雙引號(而不是單引號)以允許 shell 擴展我幾乎無法控制的變數的事情。相反,使用
awk
:awk -F '=' ' BEGIN { OFS = FS } NR == FNR { password = $0; next } $1 == "DB_PASSWORD" { sub("=.*",""); $2 = password }; 1' /root/.mysql/db00.yml.db .env >.env.new && mv .env.new .env
這首先從第一個文件的第一行讀取密碼(假設這僅包含帶有逐字密碼的單行)。
然後它將您的
.env
文件視為 -=
分隔欄位的文件。當一行的第一個欄位是
DB_PASSWORD
時,它會清除該行第一個欄位之後的所有內容=
(以防舊密碼包含=
),並將密碼作為第二個欄位插入。所有行,無論是否修改,都輸出到
.env.new
,然後該文件將舊的替換.env
為mv
。至關重要的是,我從不將從這兩個文件中的任何一個讀取的數據用作程序中的程式碼
awk
,並且我從不允許awk
將密碼的任何部分視為特殊的。請注意,在呼叫中使用密碼作為替換字元串sub()
會有問題,因為這會將&
字元串中的任何字元串視為特殊字元串。