我有一個 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 僅等待cmd2
(cmd1
據說是非同步運行(或在互動式 shell 中運行時在背景運行)),而在第三種情況下是 for cmd1
(cmd2
非同步)。
在:
< "$(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
) 是一種明智的方法。