Linux/Bash,如何在 FIFO 队列中安排命令?

Linux/Bash,如何在 FIFO 队列中安排命令?

我希望能够将命令安排在 FIFO 队列中运行。我不希望像“at”命令那样在未来的某个特定时间运行它们。我希望它们现在就开始运行,但不是同时运行。队列中的下一个预定命令应仅在第一个命令执行完成后运行。或者,如果我可以指定队列中可以同时运行的最大命令数,那就太好了;例如,如果同时运行的最大命令数为 2,则最多只能以 FIFO 方式从队列中取出 2 个预定命令来执行,而剩余队列中的下一个命令仅在当前正在运行的 2 个命令之一完成时才启动。

我听说 task-spooler 可以做类似的事情,但这个包似乎没有得到很好的支持/测试,也不在 Ubuntu 标准存储库中(我正在使用 Ubuntu)。如果这是最好的选择,那么请告诉我,我将使用 task-spooler,否则,我有兴趣找出用 bash 做这样的事情的最佳、最简单、最经过测试、无错误、规范的方法是什么。

更新:

简单的解决方案,如 bash 中的 ; 或 && 不起作用。当事件发生时,我需要从外部程序安排这些命令。我只是不想同时运行数百个命令实例,因此需要一个队列。有一个外部程序会触发事件,我可以在其中运行自己的命令。我想处理所有触发的事件,我不想错过任何事件,但我也不想让我的系统崩溃,所以这就是为什么我想要一个队列来处理从外部程序触发的命令。

答案1

任务后台处理程序:

http://vicerveza.homeunix.net/~viric/soft/ts/

https://launchpad.net/ubuntu/+source/task-spooler/0.7.3-1

效果很好。希望它能被包含在 Ubuntu 的软件包存储库中。

答案2

使用;

例如:
ls ; touch test ; ls

这将列出目录。只有在ls运行后,它才会运行touch test,这将创建一个名为 test 的文件。并且只有在完成后,它才会运行下一个命令。(在这种情况下,另一个ls将显示旧内容和新创建的文件)。

类似的命令有||&&

;将始终运行下一个命令。

&&只有在第一次返回成功时才会运行下一个命令。
例如:rm -rf *.mp3 && echo "Success! All MP3s deleted!"

||仅当第一个命令返回失败(非零)返回值时才会运行下一个命令。例如: rm -rf *.mp3 || echo "Error! Some files could not be deleted! Check permissions!"

如果要在后台运行命令,请附加一个与号 ( &)。
例如:
make bzimage &
mp3blaster sound.mp3
make mytestsoftware ; ls ; firefox ; make clean

将在后台运行两个命令(在本例中,内核构建需要一些时间,程序则播放一些音乐)。在前台,它会运行另一个编译作业,一旦完成,就会运行 ls、firefox 和 make clean(所有操作均按顺序执行)

有关详细信息,请参阅man bash


[评论后编辑]

用伪代码来说,像这样吗?

程序run_queue:

虽然(真)
{
   等待信号();

   While(队列不为空)
   {
       从队列中运行下一个命令。
       从队列中删除该命令。
       // 如果在执行过程中将命令添加到队列中,则
       // 队列不为空,继续处理所有队列。
   }
   // 队列现在为空,返回到 wait_for_a_signal
}
//
// 永远等待命令并将它们添加到队列中
// 当添加某些内容时,向 run_quueu 发出信号。
//
程序 add_to_queue()
{
   虽然(真)
   {
       等待事件();
       将命令附加到队列
       信号 run_queue
   }    
}

答案3

最简单的方法就是按顺序运行命令:

cmd1; cmd2; cmd3; cmdN

如果你希望运行下一个命令仅有的如果上一个命令成功退出,则使用&&

cmd1 && cmd2 && cmd3 && cmdN

这是我所知道的唯一一种可以实现你想要的功能的 bash 原生方式。如果你需要作业控制(设置并行作业数量等),你可以尝试安装一个队列管理器,例如扭矩但如果您只想按顺序启动作业,那么这似乎有些小题大做。

答案4

除了任务后台处理程序,我几乎找不到任何其他可以满足此需求的东西。Tsp 很棒,但我并不总是能够在我必须工作的每台服务器上编译或安装它。

我已经为此苦苦挣扎了一段时间,经过 3 次迭代(实际上从更复杂到更简单),我想出了一个纯 bash 实现,到目前为止似乎运行良好。你可以在https://github.com/sitaramc/bq

Bq 利用了 Unix 上的事实,“mv”(在同一个文件系统内)是一个原子操作,满足其所有的锁定需求。

它只是一个 bash 脚本,因此安装很简单。

该脚本有大量注释,如果您愿意的话,您可以在几分钟内查看它。

相关内容