![Shell 脚本是否按顺序执行命令?](https://linux22.com/image/95430/Shell%20%E8%84%9A%E6%9C%AC%E6%98%AF%E5%90%A6%E6%8C%89%E9%A1%BA%E5%BA%8F%E6%89%A7%E8%A1%8C%E5%91%BD%E4%BB%A4%EF%BC%9F.png)
我有一个 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
),这是一种明智的方法。