2010-09-10 62 views
2

我目前已經有一個數千行的bash腳本,它發送各種查詢MySQL來爲munin生成適用的輸出。在bash中處理MySQL結果

截至目前爲止的結果只是這是沒有問題的數字,但我現在面臨着挑戰的形式更復雜的查詢工作:

$ echo "SELECT id, name FROM type ORDER BY sort" | mysql test 
id  name 
2  Name1 
1  Name2 
3  Name3 

從這個結果我需要存儲id和名稱(及其各自的關聯),並根據需要執行進一步查詢的id,例如SELECT COUNT(*) FROM somedata WHERE type = 2和後面的輸出結果與第一個結果的相關name列配對。

我很容易就知道如何在PHP/Ruby中做到這一點,但我想省掉另一個過程,特別是因爲它定期輪詢,但我完全失去了從bash開始的地方。

無論如何,使用bash可能是錯誤的方法,我應該分叉?我正在使用GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)

回答

0

無論如何,您將會像「放手」一樣將它放到mysql命令行客戶端程序中。所以無論哪種方式,你都會產生流程創造的開銷。隨着你對每個查詢使用一個新的mysql調用的方法,你也要多次連接和驗證mysqld服務器的代價。這很貴,但如果這個應用程序不能擴展,花費可能並不重要。

防止sql注入是另一回事。如果你提示用戶輸入她的名字,她回答「薩利;丟表類型」;她在笑,你被搞砸了。

對於某些邏輯的數據庫訪問非常重要的領域,使用更具表現力的語言可能是明智的選擇。 Ruby,PHP,PERL都是不錯的選擇。 PERL恰好被調整並設計爲在shell腳本控制下快速運行。

+0

我選擇了fork方法;我在另一個腳本過程(PHP)中執行此操作。我最初不想將其他依賴項引入到我的bash腳本中,該腳本只分析出「mysql」,但似乎並不可行。謝謝 – mark 2010-09-22 12:29:09

5

您將使用while read循環來處理該命令的輸出。

echo "SELECT id, name FROM type ORDER BY sort" | mysql test | while read -r line 
do 
    # you could use an if statement to skip the header line 
    do_something "$line" 
done 

或將其存儲在一個陣列:

while read -r line 
do 
    array+=("$line") 
done < <(echo "SELECT id, name FROM type ORDER BY sort" | mysql test) 

這是該技術的一般概述。如果您有更具體的問題單獨發佈或如果他們非常簡單發佈他們的評論或編輯您的原始問題。

+0

謝謝,我想我的具體問題是:我最終從第一個結果中得到的結果是簡單的'id => name'散列,首先我需要迭代所有ID以獲取更多數據並獲取每個我需要的數據用'name'返回。有沒有辦法在bash中使用這種結構(哈希,字典)? – mark 2010-09-11 00:23:36

+0

@mark:Bash 4有關聯數組,但我認爲你應該可以在mysql中做你正在談論的內容。 – 2010-09-11 14:46:03

5

我的例子不是Bash,但我想指出我的參數在調用mysql命令時,他們抑制了拳擊和標題。

#!/bin/sh 

mysql dbname -B -N -s -e "SELECT * FROM tbl" | while read -r line 
do 
    echo "$line" | cut -f1 # outputs col #1 
    echo "$line" | cut -f2 # outputs col #2 
    echo "$line" | cut -f3 # outputs col #3 
done 
+0

'-r'做什麼? – 2016-05-17 08:41:52

+1

http://unix.stackexchange.com/questions/192786/what-is-the-meaning-of-read-r (它可以防止mysql數據中的反斜槓消失/作爲轉義字符) – Leo 2016-05-19 08:15:05