如何以队列方式运行命令

如何以队列方式运行命令

我需要将大量文件复制到各种文件夹。我可以将所有复制命令添加到 bash 脚本,然后运行该脚本,但如果我想将更多命令添加到该复制“队列”,则必须等到它完成。

有没有办法可以将命令作为队列运行,并在运行时向该队列添加更多命令?

换一种说法,我想启动一个长时间运行的任务。当该任务运行时,我想启动另一个任务,该任务实际上直到第一个任务完成才启动。然后在最后一个任务之后添加另一个任务,依此类推。这可以实现吗?

答案1

附加&到命令末尾以将其发送到后台,然后wait在运行下一个命令之前对其进行操作。例如:

$ command1 &
$ wait; command2 &
$ wait; command3 &
$ ...

答案2

at实用程序以在指定时间运行命令而闻名,它还具有队列功能,可以要求立即开始运行命令。它从标准输入读取要运行的命令。

echo 'command1 --option arg1 arg2' | at -q myqueue now
echo 'command2 ...' | at -q myqueue now

batch命令相当于at -q b -m now-m意味着命令输出(如果有)将通过邮件发送给您,就像 cron 一样)。并非所有的 unix 变体都支持队列名称(-q myqueue);您可能只能使用名为的单个队列b。Linux 的at队列名称仅限于单字母队列名称。

答案3

Brad 和 Mankoff 的解决方案都是很好的建议。另一个类似于两者结合的方法是使用GNU 屏幕来实现队列。这样做的好处是可以在后台运行,您可以随时检查它,并且排队新命令只会将它们粘贴到缓冲区中,以便在先前的命令退出后执行。

第一次运行:

$ screen -d -m -S queue

(顺便说一句,现在是玩一些很棒的游戏的好时机。screenrc 文件

这将为您生成一个名为队列的后台屏幕会话。

现在,根据需要排队任意数量的命令:

screen -S queue -X stuff "echo first; sleep 4; echo second^M"

我在上面执行了多个命令只是为了测试。您的用例可能更像:

screen -S queue -X stuff "echo first^M"
screen -S queue -X stuff "echo second^M"

请注意,上面一行中的“^M”是一种获取嵌入换行符的方法,该换行符将在屏幕将其填充到现有 bash shell 后进行解释。使用“CTL-V, ”获取该序列。

制作一些简单的 shell 脚本来自动化并排队命令是相当容易的。然后,每当您想要检查后台队列的状态时,您都可以通过以下方式重新连接:

screen -S queue -r

从技术上讲,您甚至不需要命名您的屏幕会话,它就会正常工作,但是一旦您迷上它,您就会希望让它一直运行。;-)

当然,如果您这样做,另一个好方法是将当前窗口之一命名为“队列”并使用:

screen -S queue -p queue -X stuff "command"

答案4

我也经常需要这样的东西。我写了一个名为的小实用程序,after每当其他进程完成时,它都会执行一个命令。它看起来像这样:

#!/usr/bin/perl

my $pid = shift;
die "Usage: $0 <pid> <command...>" unless $pid =~ /^\d+$/ && @ARGV;

print STDERR "Queueing process $$ after process $pid\n";
sleep 1 while -e "/proc/$pid";
exec @ARGV;

然后像这样运行它:

% command1 arg1 arg2 ...  # creates pid=2853
% after 2853 command2 arg1 arg2 ... # creates pid=9564
% after 9564 command3 arg1 arg2 ...

与其他方法相比,这种方法的一大优势在于,第一份工作不需要以任何特殊方式运行,您可以按照任何流程完成新工作。

相关内容