MySQL - 為什麼我的 BASH 腳本插入/更新查詢不能正常工作?
**背景:**我有一個 MySQL 表,用於儲存大量主機的 IP 地址。這是一個簡單的表(主機 xyz -> ip1、ip2、ip3)。這些主機會將帶有其 ip 地址的平面文件寫入中央伺服器(保存 MySQL 數據庫的地方),一個簡單的 BASH shell 腳本將處理該文件並將資訊插入/更新到 MySQL 數據庫的 ip 表中。
**我的舊ip呢?**一切正常,除了我注意到如果主機未能將其 IP 地址之一寫入平面文件,BASH shell 腳本中的插入/更新查詢將刪除舊的 IP 地址。我想保留那個IP地址。
**我應該使用 COALESCE 對嗎?**好吧,我用 COALESCE 重建了我的查詢,它可以在 phpMyAdmin 和 mysql 終端中執行。
**問題:**我將閃亮的新查詢放入 BASH shell 腳本中,但它仍然會刪除我的舊 ips(插入/更新之前主機存在的 ips)。
我可以整天將查詢複製並粘貼到 mysql 終端或 phpMyAdmin 中,它的行為完全符合我的要求。當我讓 bash shell 腳本執行此操作時,它會清除查詢中未明確設置的任何內容。
我以非常詳細的方式執行查詢以查看所有內容。我將相同的 IP 地址移動到不同的 eth#s,但是當通過 bash shell 腳本執行查詢時,舊的地址會不斷被刪除。我將相同的查詢複製/粘貼到 phpMyAdmin 或 mysql 終端中,它工作正常——沒有 ips 被刪除。
第一次使用 eth3=ip 執行(通過 mysql):
詢問:
INSERT INTO ip (host_id ,eth0 ,eth1 ,eth2 ,eth3) VALUES ('HOST1234' ,NULL ,NULL ,NULL ,INET_ATON('172.16.5.83')) ON DUPLICATE KEY UPDATE eth0 = COALESCE(NULL,eth0) ,eth1 = COALESCE(NULL,eth1) ,eth2 = COALESCE(NULL,eth2) ,eth3 = COALESCE(INET_ATON('172.16.5.83'),eth3)
結果:
host_id eth0 eth1 eth2 eth3 ========================================================== HOST1234 NULL NULL NULL 2886731091
第二次使用 eth2=ip 執行(通過 mysql):
詢問:
INSERT INTO ip (host_id ,eth0 ,eth1 ,eth2 ,eth3) VALUES ('HOST1234' ,NULL ,NULL ,INET_ATON('172.16.5.83') ,NULL) ON DUPLICATE KEY UPDATE eth0 = COALESCE(NULL,eth0) ,eth1 = COALESCE(NULL,eth1) ,eth2 = COALESCE(INET_ATON('172.16.5.83'),eth2) ,eth3 = COALESCE(NULL,eth3)
結果:
host_id eth0 eth1 eth2 eth3 ========================================================== HOST1234 NULL NULL 2886731091 2886731091
使用 eth3=ip 進行第三次執行(通過 bash 腳本):
詢問:
INSERT INTO ip (host_id ,eth0 ,eth1 ,eth2 ,eth3) VALUES ('HOST1234' ,NULL ,NULL ,NULL ,INET_ATON('172.16.5.83')) ON DUPLICATE KEY UPDATE eth0 = COALESCE(NULL,eth0) ,eth1 = COALESCE(NULL,eth1) ,eth2 = COALESCE(NULL,eth2) ,eth3 = COALESCE(INET_ATON('172.16.5.83'),eth3)
結果:
host_id eth0 eth1 eth2 eth3 ========================================================== HOST1234 NULL NULL NULL 2886731091
我希望這是有道理的。我已經花了大約 16 個小時來嘗試不同的方法,但我無法弄清楚這一點。請幫忙。我將提供您可能需要的任何其他合格資訊,以幫助我找到答案。謝謝!
BASH 外殼腳本:
#!/bin/bash file_path="/IP/" while true; do file_name=`find $file_path -mount -maxdepth 1 -type f -name "*.IP*" -printf "%f\n" | head -1` if [ "$file_name" != "" ];then echo "$file_name" host_id=`cat $file_path$file_name | grep "HOST_ID" | sed 's/^.*=//' | tr '[:lower:]' '[:upper:]' | cut -c1-13` eth0=`cat $file_path$file_name | grep "ETH0" | sed 's/^.*=//'` if [ "$eth0" != "" ];then eth0="INET_ATON('$eth0')" else eth0=NULL fi eth1=`cat $file_path$file_name | grep "ETH1" | sed 's/^.*=//'` if [ "$eth1" != "" ];then eth1="INET_ATON('$eth1')" else eth1=NULL fi eth2=`cat $file_path$file_name | grep "ETH2" | sed 's/^.*=//'` if [ "$eth2" != "" ];then eth2="INET_ATON('$eth2')" else eth2=NULL fi eth3=`cat $file_path$file_name | grep "ETH3" | sed 's/^.*=//'` if [ "$eth3" != "" ];then eth3="INET_ATON('$eth3')" else eth3=NULL fi mysql -v -v -u root -ppassword ccbu<<EOFMYSQL INSERT INTO ip (host_id ,eth0 ,eth1 ,eth2 ,eth3) VALUES ('$host_id' ,$eth0 ,$eth1 ,$eth2 ,$eth3) ON DUPLICATE KEY UPDATE eth0 = COALESCE($eth0,eth0) ,eth1 = COALESCE($eth1,eth1) ,eth2 = COALESCE($eth2,eth2) ,eth3 = COALESCE($eth3,eth3); EOFMYSQL sudo rm -fv $file_path$file_name fi done
範例 IP 文件:
HOST_ID=HOST1234 ETH3=172.16.5.83
SQL小提琴:
**解決方案:**重啟伺服器
我討厭我的生活…
您向我們展示的查詢永遠無法執行您顯示為“第二次執行”的內容。你需要類似的東西
insert into ip (host_id, eth3) values ('HOST1234', inet_aton('172.16.5.83')) ON DUPLICATE KEY UPDATE eth0 = COALESCE(eth0,eth1) ,eth1 = COALESCE(eth1,eth2) ,eth2 = COALESCE(eth2,eth3) ,eth3 = COALESCE(eth3,values(eth3))
使用空參數合併沒有任何意義,因為您知道結果。我用一個新值填充 eth3,將舊值移到前面,直到所有四列都被填滿。此後,進一步的插入無效。
以及如何修改 bash 腳本的範例(每個文件只讀一次):
#!/bin/bash file_path="/tmp/" typeset -u host_id while true; do for file_name in $file_path/*.IP* do if [ "$file_name" != "$file_path/*.IP*" ];then echo "$file_name" eth0=NULL eth1=NULL eth2=NULL eth3=NULL while read LINE do case "$LINE" in HOST_ID=*) host_id=${LINE/*=} ;; ETH0=*|ETH1=*|ETH2=*|ETH3=*) ethn=${LINE/=*/} ethn=${ethn/ETH/} typeset eth${ethn}="INET_ATON('${LINE/*=/}')" ;; esac done < $file_name echo $host_id $eth0 $eth1 $eth2 $eth3 else echo "Here be no files! :-(" fi done sleep 5 done
在“echo”之後添加mysql更新 $ host_id $ eth0 $ eth1 $ eth2 $eth3”。