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
Était-ce utile?

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

Il y a un backtick, tutoriel système et shell

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top