Perl REGEX sortie correspondant de `w commande -hs`
Question
Je suis en train d'écrire un script Perl qui fonctionnera mieux avec kwrited
de KDE, qui, pour autant que je peux dire, est connecté à un pts et met chaque ligne qu'il reçoit par les notifications de la zone de notification de KDE avec le titre "démon d'écriture de KDE".
Malheureusement, il fait une notification distincte pour chaque ligne, de sorte qu'il le plateau envoie des pourriels système avec des messages sur multilignes régulier vieux écriture, et pour une raison quelconque, il coupe la toute dernière ligne du message lors de l'utilisation mur . messages d'une ligne sont également goners.
J'espérais aussi de faire en sorte qu'elle puisse diffuser à travers un réseau local avec les clients épais. Avant de commencer ce (qui nécessiterait SSH, bien sûr), j'ai essayé de faire une version SSH-moins pour vous assurer qu'il fonctionne. Malheureusement, il ne fonctionne pas:
perl ./write.pl "Testing 1 2 3"
où ce qui suit est le contenu de ./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"
}
produit l'erreur suivante:
$ 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' > '
D'une certaine façon, les expressions régulières et / ou l'évasion backtick dans le traitement $possibledevice
ne fonctionnent pas correctement, parce que là où kwrited est connecté à /dev/pts/0
, ce qui suit fonctionne parfaitement:
$ perl write.pl "Testing 1 2 3" /dev/pts/0
La solution
Vous fournissez un seul argument de ligne de commande (chaîne "Testing 1 2 3
").
$ argv [1] est FNUD.
$device
est FNUD à cause de la logique à l'intérieur if ($ARGV[0] ne "")
.
Alors votre commande echo
de shell les réoriente à rien ( « echo something >
») et donc la coquille se plaint (et c'est là avertissement Perl « périphérique $ non défini » est de même).
Si vous vouliez dire l'appareil à « 1 », puis un guillemet votre chaîne de l'argumentation (perl write.pl Testing 1 2 3
) sur la ligne de commande.
En outre, s'il vous plaît envisager d'ouvrir $ appareil sous forme de fichier pour l'écriture et l'impression « $ message » à la poignée de fichier. Il est un peu plus idiomatiques Perl et moins sujettes à des problèmes découlant de transitions perl-à-shell / citant / etc ...
Autres conseils
Un problème est votre '
autour de l'appel système tenté. Aucune interpolation a lieu à l'intérieur des guillemets simples en Perl.
Si vous regardez un cas simple:
#!/usr/bin/perl
use strict;
use warnings;
my $possibledevice = '`w -hs | grep "/usr/bin/kwrited"`'; #Where is kwrited?
print $possibledevice;
La sortie est:
`w -hs | grep "/usr/bin/kwrited"`
Ainsi, votre appel shell n'a jamais lieu. La solution est de changer l'appel shell à quelque chose comme ceci:
my $possibledevice = `w -hs | grep \"/usr/bin/kwrited\"`; #shud b there...
#or
my $possibledevice = qx$w -hs | grep \"/usr/bin/kwrited\"$; #alternate form
Vous pouvez lire sur les différents opérateurs citation comme dans perlop ou perldoc ICI