我需要将大量文件复制到各种文件夹。我可以将所有复制命令添加到 bash 脚本,然后运行该脚本,但如果我想将更多命令添加到该复制“队列”,则必须等到它完成。
有没有办法可以将命令作为队列运行,并在运行时向该队列添加更多命令?
换一种说法,我想启动一个长时间运行的任务。当该任务运行时,我想启动另一个任务,该任务实际上直到第一个任务完成才启动。然后在最后一个任务之后添加另一个任务,依此类推。这可以实现吗?
答案1
附加&
到命令末尾以将其发送到后台,然后wait
在运行下一个命令之前对其进行操作。例如:
$ command1 &
$ wait; command2 &
$ wait; command3 &
$ ...
答案2
答案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 ...
与其他方法相比,这种方法的一大优势在于,第一份工作不需要以任何特殊方式运行,您可以按照任何流程完成新工作。