在某些系统上,某些命令(例如df
和prtdiag
)(仅限 Sun)可能会由于各种原因无限期挂起。我正在尝试强化我的ksh
脚本,以便如果它们遇到这些问题,它们会失败而不是无限期地停滞。为此,我计划使用该timeout
命令,但它并不是在 100% 的足迹上普遍可用,因此我必须有条件地仅使用timeout
它存在的情况,如果不存在则使用裸命令。我想为此找到一种紧凑的单行代码,因为我需要将其插入到众多现有的命令链中,同时尽量减少复杂性的增加。
对于大多数命令来说,这很简单。但在超时时(124、143 或 271)timeout
返回非零状态代码,而不仅仅是因为不存在而无法运行时(1 或 127)。因此,简单的||
操作员无法区分“无此命令”和“操作超时”。结果,这是行不通的:
(timeout 5 df || df) # will execute bare df if there is no timeout *or* if the first df times out, thus hanging
出于同样的原因,测试超时命令而不尝试执行它的另一个选项也不起作用。超时条件下的超时本身看起来||
就像超时命令不存在一样:
(command -v timeout >/dev/null && timeout 5 df || df) # same result
我需要一个紧凑的if-then-else返回代码,其中最后一段 ( else ) 的返回代码仅由第一段 ( if ) 驱动,而不受中间段 ( then ) 的影响。如果该timeout
命令存在,则使用它,否则,执行裸命令。我不希望超时条件导致执行裸命令。
这是一种可以正确工作的方法,通过测试两次:
(command -v timeout >/dev/null || df; command -v timeout >/dev/null && timeout 5 df)
但这感觉不太优雅;我必须重复command -v timeout >/dev/null
两次。另一种仅适用于一次测试的选项:
(command -v timeout >/dev/null; if [ $? -eq 0 ]; then timeout 5 df; else df; fi)
但是带有分号的显式if-then-else-fi之类的感觉很粗暴,而且没有应有的紧凑。
对于更干净、更紧凑的方法有什么建议吗?它需要能够在ksh88
AIX、Sun、HP-UX 和 Linux 上运行。
请注意,
A && B || C
如果 A或B 失败,则执行 C。您需要使用if
正确分隔 B 和 C。听起来您想要创建一个函数,并且可能在库文件中:如果这是在文件中
my_timeout.ksh
然后在您的脚本中最小的更改是:
ksh
.
将在 PATH 中查找要获取的文件(至少在 ksh93 中,对于 ksh88 不是 100% 确定)。否则,通过绝对路径获取它。我会创建一个目录
timeout
,并且:/bin/
和之前/usr/bin
)df
:(显然仅适用于您想要超时的命令)