2010-06-06 125 views
0

我正在尝试编写一个Perl脚本,它可以更好地处理KDE的kwrited,据我所知,它可以连接到pts,并将每一行通过KDE系统托盘接收标题为“KDE写入守护程序”的通知。`w -hs`命令的Perl正则表达式匹配输出

不幸的是,它使每行一个单独的通知,所以修建垃圾了多邮件系统托盘上普通的旧write,以及由于某种原因,使用wall时切断消息的整个最后一行。单线消息也是流行的。

我也希望能够通过局域网与广泛的客户端进行广播。在开始之前(当然需要SSH),我尝试制作一个无SSH的版本以确保它可以正常工作。不幸的是,它并不:

perl ./write.pl "Testing 1 2 3" 

,其中以下是./write.pl内容:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $message = ""; 
my $device = ""; 
my $possibledevice = '`w -hs | grep "/usr/bin/kwrited"`'; #Where is kwrited? 
$possibledevice =~ s/^[^\t][\t]//; 
$possibledevice =~ s/[\t][^\t][\t ]\/usr\/bin\/kwrited$//; 
$possibledevice = '/dev/'.$possibledevice; 
unless ($possibledevice eq "") { 
    $device = $possibledevice; 
} 

if ($ARGV[0] ne "") { 
    $message = $ARGV[0]; 
    $device = $ARGV[1]; 
} 
else { 
    $device = $ARGV[0] unless $ARGV[0] eq ""; 
    while (<STDIN>) { 
     chomp; 
     $message .= <STDIN>; 
    } 
} 

if ($message ne "") { 
    system "echo \'$message\' > $device"; 
} 
else { 
    print "Error: empty message" 
} 

产生以下错误:

$ perl write.pl "Testing 1 2 3" 
Use of uninitialized value $device in concatenation (.) or string at write.pl line 29. 
sh: -c: line 0: syntax error near unexpected token `newline' 
sh: -c: line 0: `echo 'foo' > ' 

不知何故,正则表达式和/或在处理$possibledevice中的反引号溢出无法正常工作,因为其中kwrited连接到/dev/pts/0,下面的wo rks完美:

$ perl write.pl "Testing 1 2 3" /dev/pts/0 

回答

4

您只提供一个命令行参数(字符串“Testing 1 2 3”)。

所以$ ARGV [1]是undef。

因此$device是undef,因为if ($ARGV[0] ne "")内部的逻辑。因此你的shell的echo命令重定向到什么都没有(“echo something >”),因此shell抱怨(这也是“undefined $ device”Perl的警告所在)。

如果您的设备为“1”,请在命令行中取消引用您的参数字符串(perl write.pl Testing 1 2 3)。

另外,请考虑打开$设备作为文件写入和打印文件句柄“$ message”。这是一个更加惯用的Perl,不太容易产生perl-to-shell转换/引用等问题。

+0

在参数处理条件中添加更多内容修复了它。正则表达式确实需要一些修改,但它现在起作用。非常感谢你! – mmirate 2010-06-06 19:28:03

0

一个问题是您的'周围的尝试系统调用。 Perl中的单引号内没有内插。

如果你看一个简单的例子:

#!/usr/bin/perl 

use strict; 
use warnings; 


my $possibledevice = '`w -hs | grep "/usr/bin/kwrited"`'; #Where is kwrited? 
print $possibledevice; 

输出是:

`w -hs | grep "/usr/bin/kwrited"` 

所以你的shell通话从未发生。解决方法是在外壳的呼叫切换到更多的东西是这样的:

my $possibledevice = `w -hs | grep \"/usr/bin/kwrited\"`; #shud b there... 
#or 
my $possibledevice = qx$w -hs | grep \"/usr/bin/kwrited\"$; #alternate form 

您可以了解不同的报价像perlop中或在的perldoc运营商HERE

有一个反引号,系统和外壳教程HERE

+0

我刚才试过,没有效果:我得到完全相同的错误。 正则表达式仍然存在问题。 – mmirate 2010-06-06 18:58:36

+0

DVK具有以下解决方案的其他部分...您仍然需要更改您的shell引号或者什么都不会发生。 – dawg 2010-06-06 19:16:18