开发者

Perl regex matching output from `w -hs` command

I'm trying to write a Perl script that will work better with KDE's kwrited, which, as far as I can tell, is connected to a pts and puts every line it receives through the KDE system tray notifications with the title "KDE write daemon".

Unfortunately, it makes a separate notification for each and every line, so it spams up the system tray with multiline messages on regular old write, and for some reason it cuts off the entire last line of the message when using wall. One-line messages are also goners.

I was also hoping to make it so that it could broadcast across a LAN with thick clients. Before starting on that (which would require SSH, of course), I tried to make an SSH-less version to make开发者_JAVA百科 sure it works. Unfortunately, it doesn't:

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

where the following is the contents of ./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"
}

produces the following error:

$ 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' > '

Somehow, the regular expressions and/or the backtick escape in processing $possibledevice are not working properly, because where kwrited is connected to /dev/pts/0, the following works perfectly:

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


You supply only ONE command line argument (string "Testing 1 2 3").

So $ARGV[1] is undef.

So $device is undef because of the logic inside if ($ARGV[0] ne "") .

So your shell's echo command redirects to nothing ("echo something >") and thus shell complains (and that's where "undefined $device" Perl warning is from as well).

If you meant the device to be "1", then un-quote your argument string (perl write.pl Testing 1 2 3) on command line.

Also, please consider opening $device as a file for writing and printing "$message" to the file handle. It's a bit more idiomatic Perl and less prone to problems stemming from perl-to-shell transitions/quoting/etc...


One problem is your ' around the attempted system call. No interpolation takes place inside single quotes in Perl.

If you look at a simple case:

#!/usr/bin/perl

use strict;
use warnings;


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

The output is:

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

So your shell call never takes place. The fix is to change the shell call to something more like this:

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

You can read about the different quote like operators in perlop or at perldoc HERE

There is a backtick, system and shell tutorial HERE

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜