2016-09-23 46 views
0

上下文:我正在製作自己的i3-Bar腳本來讀取在後臺運行的其他(異步)腳本的輸出,並將它們連接起來,然後將它們連接到i3-Bar本身。定期從異步背景腳本中讀取輸出

我通過輸出的方式是純文件,我猜(邏輯上)問題是文件有時同時讀取和寫入。重現此行爲的最佳方法是通過暫停電腦,然後將其喚醒 - 我不知道確切原因,我只能繼續從我的調試日誌文件中看到。

主代碼:爲清楚起見

#!/usr/bin/env bash 
cd "${0%/*}"; 

trap "kill -- -$$" EXIT; #The bg. scripts are on a while [ 1 ] loop, have to kill them. 

rm -r ../input/*; 
mkdir ../input/; #Just in case. 

for tFile in ./*; do 
    #Run all of the available scripts in the current directory in the background. 
    if [ $(basename $tFile) != "main.sh" ]; then ("$tFile" &); fi; 
done; 

echo -e '{ "version": 1 }\n['; #I3-Bar can use infinite array of JSON input. 

while [ 1 ]; do 

    input=../input/*; #All of the scripts put their output in this folder as separate text files 

    input=$(sort -nr <(printf "%s\n" $input)); 

    output=""; 

    for tFile in $input; do 
     #Read and add all of the files to one output string. 
     if [ $tFile == "../input/*" ]; then break; fi; 
     output+="$(cat $tFile),"; 
    done; 

    if [ "$output" == "" ]; then 
     echo -e "[{\"full_text\":\"ERR: No input files found\",\"color\":\"#ff0000\"}],\n"; 
    else 
     echo -e "[${output::-1}],\n"; 
    fi; 

    sleep 0.2s; 
done; 

添加的註釋示例輸入腳本:

#!/usr/bin/env bash 
cd "${0%/*}"; 

while [ 1 ]; do 
    echo -e "{" \ 
     "\"name\":\"clock\"," \ 
     "\"separator_block_width\":12," \ 
     "\"full_text\":\"$(date +"%H:%M:%S")\"}" > ../input/0_clock; 
    sleep 1; 
done; 

的問題

問題不是腳本本身,但事實證明,i3-Bar收到了格式不正確的JSON輸入( - >解析錯誤),並終止 - 稍後我會顯示此類日誌。

另一個問題是,後臺腳本應該異步運行,因爲有些需要每1秒鐘更新一次,並且每1分鐘纔會更新一次,等等。因此,使用FIFO並不是一個真正的選擇,除非我創建一些醜陋的低效率的黑客東西。

我知道這裏有需要IPC,但我不知道如何高效這樣做。從隨機崩潰

輸出

腳本 - 醒來的錯誤看起來是一樣的

[{ "separator_block_width":12, "color":"#BAF2F8", "full_text":"192.168.1.104 "},{ "separator_block_width":12, "color":"#BAF2F8", "full_text":"100%"}], 

[{ "separator_block_width":12, "color":"#BAF2F8", "full_text":"192.168.1.104 "},,], 

(由第二行創建錯誤) 正如你看到的,主要的腳本試圖讀取該文件,沒有按」噸得到任何輸出,但逗號仍然存在 - >畸形的JSON。

+0

考慮使用'jq'來生成和合並您的JSON文件。 'jq --slurp'。' ../ input/*單獨將您的輸入文件合併到單個JSON數組中。 – chepner

回答

1

眼前的錯誤很容易解決:如果相應的文件是空不追加到output的條目:

for tFile in $input; do 
    [[ $tFile != "../input/*" ]] && 
     [[ -s $tFile ]] && 
     output+="$(<$tFile)," 
done 

存在潛在的競爭條件在這裏,雖然。僅僅因爲一個特定的輸入文件存在並不意味着數據已經完全寫入它了。我會改變你的輸入腳本,看起來像

#!/usr/bin/env bash 
cd "${0%/*}"; 

while true; do 
    o=$(mktemp) 
    printf '{"name": "clock", "separator_block_width": 12, "full_text": %(%H:%M:%S)T}\n' > "$o" 
    mv "$o" ../input/0_clock 
    sleep 1 
done 

此外,${output%,}是必要時修剪後面的逗號更安全的方式。

+0

我試着檢查文件是否存在,但我不知道'-s'選項,謝謝。我根據你的建議編輯我的腳本。 – areuz

+0

嗯,我得說,它幾乎奏效,但每10-20分鐘一次它再次做同樣的事情,沒有什麼改變,只是錯誤率。現在大約每8000個週期。我真的正在考慮一種不同的方法 - IPC,但我不知道該怎麼做, – areuz