如何使用命令前缀工具更轻松地指定批量任务?

如何使用命令前缀工具更轻松地指定批量任务?

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

相关内容