2016-01-15 135 views
0

我寫了一個簡短的bash腳本,每10秒收集一次CPU溫度並將其輸出到一個文件以及其他一些數據。在終端中運行腳本工作得很好。但是,一旦我安裝腳本在啓動時運行,我遇到兩個問題:Bash腳本無限循環關閉

-opening在gedit中的結果所產生的.txt文件: 「的gedit一直沒有能夠檢測到的字符編碼 請檢查。你並沒有試圖打開一個二進制文件。「 從菜單中選擇一個字符編碼,然後再試一次。「使用Libre Writer打開文件可以正常工作,並且文件的數據是正確的。

- 第一次在腳本放入/ etc/init後嘗試關閉。 。d /和運行update-rc.d的電腦莫名其妙地需要長期做,到我必須手動關閉點

這是腳本代碼:

#!/bin/bash 

readonly DIR_PATH='/home/ivan/Documents/temp_data/' # path to output dir, change to yours, don't use HOME variable 

while true; do 
    temps_str=$(sensors | grep "Physical" | tr -dc "[:digit:][^ °.C]") # extract numbers from sensors command output 
    temps_str=${temps_str:5} # remove first 5 characters, they are ' ', ' ', '0', ' ', ' ' and useless 
    temps_array=($temps_str) # convert string to array 

    temp_now=${temps_array[0]} # CPU temp now 
    temp_high=${temps_array[1]} # highest CPU temp recorded in this session 
    temp_max=${temps_array[2]} # CPU temp at which PC turns off 

    dt=$(date +%d-%m-%Y) # date, format: dd-mm-yyyy 
    time=$(date +%H:%M:%S) # time, format: HH:MM:SS 

    # create output directory if it doesn't already exist 
    if [ ! -d $DIR_PATH ]; then 
     mkdir -m 755 $DIR_PATH 
    fi 

    echo $time $temp_now $temp_high $temp_max >> ${DIR_PATH}${dt}.txt # write to output file 

    sleep 10 # wait 10 seconds 
done 

這是格式輸出文件:

17時22分21秒58.0℃,87.0℃,105.0℃,

17點22分31秒56.0℃,87.0℃,105.0℃,

十七時22分41秒58.0℃,87.0℃,105.0℃的

17時22分51秒59.0℃,87.0℃,105.0℃,

17時23分01秒58.0℃,87.0℃,105.0℃,

十七時23分11秒59.0℃,87.0° C 105.0℃

17:23:21 60.0℃87.0℃105.0℃

17點23分32秒63.0℃,87.0℃,105.0℃,

17點23分42秒63.0℃,87.0℃,105.0℃,

當我得到 '永恆關閉',I手動關閉它。重新啓動後,文件顯示腳本仍在運行並在PC被凍結時寫入文件,然後是一行#s(可能在手動關閉期間寫入該行)。我想知道是什麼原因導致凍結,爲什麼.txt文件字符集會「損壞」?

+0

您在這裏有兩個完全不相關的問題:一個關於'gedit'處理非ascii字符,另一個關於System-V樣式init腳本。我想你應該把注意力集中在init.d問題上,並將gedit問題放在一個單獨的問題中。爲了簡化gedit問題,只需創建一個帶有度數標誌的簡單文件即可創建問題。 – rici

+0

這條'#'聽起來很可怕。它可能是破碎的編碼的來源。或者你的意思是一行數字?無論哪種方式 - 當您正常啓動和關閉時,或僅當計算機過熱時,會出現同樣的問題嗎? –

+0

我試圖回答init.d問題。根據我上面的建議,我沒有包括對gedit問題的回答,我重申,它是完全正交的。 – rici

回答

0

/etc/init.d中的腳本有望啓動和停止服務。所以他們需要準備好接受命令行參數startstop。 (如果他們也接受像restartstatus參數,這是一個獎金。)

當你把一個符號鏈接到這些腳本中的一個目錄中/etc/rcN.d,那麼該腳本將與任何參數startstop調用:

  • 在啓動時,該參數依賴於符號鏈接的名稱是否與Sstart)或K開始(stop - 字母代表「殺死」)。

  • 關閉時,參數將爲stop

(以上是Debian的行爲,從Debian policy manual拍攝。)

你的劇本是這樣的形式不是。它只是運行監控程序。所以當它被參數stop調用時,它不會停止監視。它將啓動另一個監控循環,其中永不終止。因爲它是從關閉序列中直接調用的,所以會阻止關閉。

通常的方法來編寫init.d腳本是基於以下幾點:

  • 當與start選項調用腳本啓動的守護進程服務(即當前的監控腳本)和寫入其PID到一個文件,其名稱與服務名稱相關。 (放置該文件的常見地點是/var/run目錄,通常使用擴展名.pid。)有一些標準實用程序可將進程作爲守護進程啓動,這可以幫助執行此任務。如果您有基於Debian的(包括Ubuntu)安裝,請查看Shell實用程序庫/lib/lsb/init-functions

  • 當使用stop選項進行調用時,該腳本使用存儲在start操作中創建的文件中的PID來對kill進程執行操作。然後刪除pid文件。

+0

只是爲了說清楚,我需要修改我的腳本,以便它接受論據。如果參數是開始的,那麼腳本應該將它的PID寫入/ var/run中的.pid文件,如果參數是stop,那麼腳本執行kill命令來結束它的進程並刪除.pid文件?即使這個檢查放在while循環之前,當PC進入關機狀態時,它仍然可以工作?或者是否需要將參數值檢查放入循環中? – krsnik93

+0

@ user2858258:不是。你需要兩個腳本。一個是實際的監控腳本,另一個是服務啓動/停止腳本。 /etc/init.d中有很多示例。你可以谷歌搜索「init.d教程」,和/或看看這個答案在一個姊妹網站:http://askubuntu.com/a/188148/488236 – rici

+0

優秀的鏈接,非常感謝你:) – krsnik93