在某些系统上,某些命令(如df
和prtdiag
)(仅限Sun)可以由于各种原因无限期地挂起。我正在尝试加强我的ksh
脚本,以便它们遇到这些挂起时,它们会失败而不是无限期地停止。为此,我计划使用timeout
命令,但它并不是100%的内存都可用,所以我必须有条件地使用timeout
*,只有当它存在 * 时,如果没有的话,我想找一个紧凑的命令-因为我需要将其插入到大量现有的命令链中,而复杂性的增加最小。
对于大多数命令来说,这很简单。但是timeout
* 在超时 *(124,143或271)时返回非零状态码,而不仅仅是因为它不存在而无法运行时(1或127)。因此,简单的||
操作符无法区分“没有这样的命令”和“操作超时”。因此,这将不起作用:
(timeout 5 df || df) # will execute bare df if there is no timeout *or* if the first df times out, thus hanging
字符串
另一个测试timeout命令而不尝试执行它的选项也因为同样的原因不起作用。超时条件下的timeout本身在||
上看起来就像timeout命令不存在一样:
(command -v timeout >/dev/null && timeout 5 df || df) # same result
型
我需要一个紧凑的 if-then-else 返回代码,其中最后一段(else)的返回代码仅由第一段(if)驱动,而不受中间一段(then)的影响。如果timeout
命令存在,则使用它,否则,执行bare命令。我不希望超时条件导致执行bare命令。
这里有一种正确的方法,通过测试两次:
(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 与分号等感觉沉重,而不是紧凑,因为它应该。
有没有更简洁、更紧凑的方法来实现这一点?它需要在AIX、Sun、HP-UX和Linux上运行旧的ksh88
。
2条答案
按热度按时间zte4gxcn1#
请注意,如果A或B失败,
A && B || C
将执行C。您需要使用if
正确分离B和C。听起来你想创建一个函数,而且很可能是在一个库文件中:如果这是在文件
my_timeout.ksh
中,字符串
然后在你的脚本中,最小的变化是:
型
ksh
.
将在PATH中查找要源的文件(至少在ksh93中,而不是100%确定ksh88)。否则,通过绝对路径来源。a6b3iqyw2#
创建一个目录
timeout
,然后:/bin/
和/usr/bin
之前)df
:字符串
(显然只适用于您希望有超时的命令)