--- title: 'Bug: Bash Arithmetic Evaluation Exit Status Pitfall' disqus: hackmd --- Bug: Bash Arithmetic Evaluation Exit Status Pitfall === 某天寫了支Daemon(使用`shell script`),上線後出現bug: ``` Dec 09 08:40:11 tw-logs run_syncLog_bin[171034]: ----------------------------------------------------- Dec 09 08:40:11 tw-logs systemd[1]: syncLog.service: Main process exited, code=exited, status=1/FAILURE Dec 09 08:40:11 tw-logs systemd[1]: syncLog.service: Failed with result 'exit-code'. Dec 09 08:40:11 tw-logs systemd[1]: Failed to start syncLog.service - syncLogFiles. ``` log message印出分隔線之後,立刻因為return code崩潰 ## Guide [TOC] ## How it works 把code拉出來看,乍看之下沒問題: ```bash= count=0 ... ... while read -r list || [ -n "list" ]; do echo "-----------------------------------------------------" ( mkdir -p "${path}/${list}" ... ... ) & ((count++)) ... ... done ``` 然而,前面加入這個參數: ```bash set -euo pipefail ``` 意思是,遇到錯誤,也就是`exit-code=1`時,直接讓script崩潰 於是問題就產生了: > [!Warning] > ((count++))是**後置運算**,先**回傳目前的值,再進行運算** 所以,while-loop第一次運作時,count會先`return 0`,再開始+1 數學運算邏輯中,數值0代表`False`;在shell得到這個"狀態"後,會將這個狀態識別(FAILURE)並反應, 回傳`FAILURE`(status=1,error) 這時就會撞到前面的: ```bash set -euo pipefail ``` 然後,script崩潰了(Failed with result: exit-code),如同設計好的一般 計畫失敗的相當成功 ![image](https://hackmd.io/_uploads/B17x9GrM-x.png) ## What should we do 事情出在哪,解法就用在哪 改成**後置運算**即可: ```bash ((++count)) ``` ## Ref. [BashPitfalls](https://gist.github.com/dsoares/7608d68538be606f3b6a6f0c557bfc8c) [How to do calculation in Bash](https://www.shell-tips.com/bash/math-arithmetic-calculation/#gsc.tab=0) [something interesting in StackOverFlow](https://stackoverflow.com/questions/69950459/bash-weirdness-exit-codes-of-arithmetic-expressions-in-relation-to-conditionals) ###### tags: `linux` `shell script` `bug`