batch
守护进程附带的工具atd
原则上非常有用,仅当系统利用率低于特定级别(默认情况下为 1.5)时才运行命令。然而,按照现代标准,使用它(以及at
)是相当难看的:您要么必须提供一个可以由 运行的脚本/bin/sh
,要么以交互方式将命令键入到基本提示中,而无需完成、颜色编码等。
真正好的是一个命令前缀工具,更像是nice
,可以将其放在任何命令前面以将其添加到批处理队列中(并且类似的实用程序at
会很方便,尽管这不是我问题的重点) 。例如,它可能像这样工作:
my-batchifying-command python some_longrunning_computational_script.py
这样的事情存在吗?如果没有,它是如何创建的?我用于zsh
我的主 shell,但bash
答案同样可以,并且可能具有更广泛的适用性。
答案1
用于zsh
简单命令:
my-batch() {print -r -- ${(qq)@} | batch}
my-batch python some_longrunning_computational_script.sh
会做的。
如果您需要更复杂的东西,如循环或重定向,您可以这样做:
my-batch eval 'for i in ...; done'
my-batch eval 'echo test > /some/file'
但请记住使用sh
,而不是zsh
语法。
如果你想避免这种情况eval
,你可以使用这个技巧:
alias my-batch=':||'
preexec()
if [[ $1 = my-batch\ * ]]; then
print -r -- "${1#my-batch }" | batch
fi
再次强调,一定要使用sh
语法。
请注意,它只能是一命令(实际上是一个管道)。如果需要多个大括号,请使用大括号:
my-batch { ls > /tmp/a; date > /tmp/b; }
上面的想法是,该my-batch
命令不执行任何操作,甚至不评估该命令的参数,因为例如my-batch echo $(date)
扩展为:|| echo $(date)
,并且preexec
每次接受命令行时都会运行该命令来完成该工作。
对于preexec
,$1
是完整的命令行不变。我们只是检查它是否以 开头"my-batch "
,删除它并将其余部分发送到batch
。
这就解释了为什么my-batch
必须位于行的开头。cmd && my-batch ...
例如,它将不起作用,并且您不能做类似的事情my-batch foo || bar
,因为它实际上会被解释为:|| foo || bar
。