这是我的第一个perl程序:
我想确保如果我离开我的机器一段时间,那么这个脚本ssh到我们的主服务器并杀死我的所有进程. (当我去吃午餐时,我会忘记杀死它们,并且它们会占用大量的cpu和内存).
我已经走到这一步了,屏幕保护程序激活杀戮开始后15分钟.
#!/usr/bin/perl my $cmd = "dbus-monitor --session \"type='signal',interface='org.gnome.ScreenSaver',member='ActiveChanged'\""; open (IN,"$cmd |"); while (<IN>) { if (m/^\s+boolean true/) { print "*** Screensaver is active ***\n"; print "*** Sleeping before megadeath....\n"; sleep(15*60); print "*** killing all jla processes on anvil...\n"; $result = `ssh anvil pkill -u jla`; print "*** should all be dead\n"; print $result; } elsif (m/^\s+boolean false/) { print "*** Screensaver is no longer active ***\n"; } }
但我想要的是在监控键盘的同时等待15分钟.如果说,’N’键被按下(在脚本运行的终端中),那么我想中止查杀并返回监视屏幕保护程序.如果在我喝咖啡时屏幕保护程序出现,这将给我一条逃生路线.
某种邦德风格的倒计时也很不错.
实际上更好的方法是在屏幕保护程序解锁时注意,如果是,则停止倒计时,返回监控模式.然后我甚至不用担心记得按N.
解决方法
正如暴民所说,线程和选择使这一点过于复杂.所以这里有一些简单明了的
Term::ReadKey,它可以让你在第一时间做你所要求的:等待按键,但是如果在15分钟内没有按下按键就超时.
#!/usr/bin/env perl use strict; use warnings; use Term::ReadKey; my $cmd = "dbus-monitor --session \"type='signal',member='ActiveChanged'\""; open(IN,"$cmd |"); ReadMode 'cbreak'; # return keypress immediately without waiting for "Enter" while (<IN>) { if (m/^\s+boolean true/) { print "*** Screensaver is active ***\n"; print "*** Sleeping before megadeath....\n"; my $key = ReadKey 900; # timeout after 900 seconds = 15 minutes if (defined $key) { print "*** A key was pressed; megadeath averted\n"; } else { print "*** killing all jla processes on anvil...\n"; my $result = `ssh anvil pkill -u jla`; print "*** should all be dead\n"; print $result; } } elsif (m/^\s+boolean false/) { print "*** Screensaver is no longer active ***\n"; } } ReadMode 'restore'; # back to normal input mode
(代码在语法上是正确的,但尚未运行,因此未经过全面测试.除了’cbreak’之外,您可能还需要设置’noecho’ReadMode以防止禁用兆路径的按键出现在屏幕上.)