Shell 腳本是否依序執行指令?

Shell 腳本是否依序執行指令?

我有一個 python 腳本,它有點不穩定,時不時會出現 SSL 錯誤。該異常是由某些庫中深埋的某些函數引發的,因此基本上沒有解決方案。

我透過建立一個帶有運行大量次的 while 循環的 shell 腳本並從該循環內執行 python 腳本來實現了一個 hacky 解決方案。

現在我希望的是,當循環的迭代開始並執行腳本時,shell 腳本內的循環保持在原來的位置,直到 python 腳本失敗並且循環的下一次迭代重新執行腳本,所以在。

這樣做有效率嗎?有更好的方法嗎?最重要的是它正確嗎?

答案1

在:

cmd1
cmd2

或者

cmd1; cmd2

它們是按順序執行的。

cmd1 && cmd2

或者

cmd1 || cmd2

它們按順序執行,但是否cmd2執行完全取決於是cmd1成功 (for &&) 還是失敗 (for ||)。

cmd1 | cmd2

或者

cmd1 & cmd2
cmd1 |& cmd2 # ksh
coproc cmd1; cmd2 # bash/zsh

或者

cmd1 <(cmd2) # ksh/zsh/bash (also yash though with a different meaning)

它們是同時執行的。在第一種情況下,有些 shell 僅在繼續執行腳本的其餘部分之前等待,cmd2而有些 shell 則兩者都等待。在第二種情況下,shell 僅等待cmd2cmd1據說是非同步運行(或在互動式 shell 中運行時在背景運行)),而在第三種情況下是 for cmd1cmd2非同步)。

在:

< "$(cmd1)" x=$(cmd2) y=$(cmd3) cmd4 "$(cmd5)" > "$(cmd6)"

命令按順序運行,但順序取決於 shell。無論如何,cmd4都會最後執行。

在:

cmd1 =(cmd2) # zsh

它們按順序執行(cmd2首先)。

請注意,在所有這些情況下,任何這些命令都可以啟動其他進程。 shell 不知道它們,所以不可能等待它們。

答案2

是的。它是正確的。考慮一下:

#!/bin/bash

while true; do
    sleep 1
    echo "Slept 1"
    echo "Exit status $?, ok."
    sleep 1
    echo "Slept 1, now executing faulty command 'ps q'"
    ps q
    echo "Exit status $?, not ok. Loop continues forever..."
done

....執行時將如下圖所示:

./loop.sh 
Slept 1
Exit status 0, ok.
Slept 1, now executing faulty command 'ps q'
ps: illegal option -- q
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
          [-u]
          [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
       ps [-L]
Exit status 1, not ok. Loop continues forever...
Slept 1
Exit status 0, ok.
Slept 1, now executing faulty command 'ps q'
ps: illegal option -- q
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
          [-u]
          [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
       ps [-L]
Exit status 1, not ok. Loop continues forever...
^C

只要循環始終存在,true循環內的程式具有哪些退出程式碼並不重要。它們將繼續按照寫入的順序執行。

這樣做有效率嗎?有更好的方法嗎?

最好的方法就是消除 Python 程式中的錯誤!

答案3

回答你的標題問題:是的,shell腳本中的命令是按順序同步執行的,因此當你的Python腳本運行時,shell會被阻止。

修復錯誤來源當然會更好,但如果這不是一個選項,那麼 shell 腳本將嘗試執行 python 腳本,直到它傳回零狀態碼 ( while true;do ./script.py; if [[ "$?" = 0]];break;done) 是一種明智的方法。

相關內容