/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
open3 og select og Resource temporarily un~
Fra : Esben Mose Hansen


Dato : 22-12-03 23:12

Hej,

Jeg har en bunke programmer skrevet i forskellige sprog, som alle udmærker
sig ved at bede om username+password, og så spytte en fil ud udfra noget
input. Disse er kædet sammen i en Makefile. Det virker fremragende, bortset
fra at det er lidt træls at skulle taste samme password 10 gange... og
desuden ville jeg gerne lave en frontend til det med lidt syntax
highlighting og sår'n. Det er jo jul :)

OK --- så vidt jeg kan se er mit problem altså følgende: Jeg ar en process
(make) der skaber noget output, dels på stdout, dels på stderr, og som
læser noget data en gang imellem (password+username). Så hvis jeg bare kan
læse det der bliver skrevet til/læst fra processen skulle det jo være let
nok.

Jeg finder hurtigt open3(), som lige er hvad jeg skal bruge. Der står en
masse om at man skal passe på, men de nævner også select() som er en kær,
gammel ven. Det skulle være en smal sag at kæde de to ting sammen, tænker
jeg. Men nej, skidtet vil ikke fungere. Uanset hvilket program jeg starter
får jeg øjeblikkeligt tilbage fra select() at der er noget fra stdout og
stderr, men hver gang der læses fra disse får jeg: "Resource temporarily
unavailable". A-hva? Jeg har lige lavet select() på den resource :(

Nogen bud? Koden, som er en simpel prototype, er nedenfor, og output under
koden. Bemærk at hvis man selecter på STDIN istedet for OUT, ERR virker det
helt fint, se evt. nederst.

-- asyn --

#!/usr/bin/perl -w
use IO::Select;
use IPC:en3;

#XXX: for the future
$running = 1;

#install signal handler
$SIG{'CHLD'} = sub {
print "Reaping...";
waitpid( $pid,0 );
print "done\n";
$running = 0;
return 1;
};
$SIG{'PIPE'} = sub {
print "Pipe broke!";
$running = 0;

return 1;
};

#Open a program. In this case a small perl script including below.
$pid = open3(\*IN, \*OUT, \*ERR, '/home/esben/hello');
#$pid = open3(\*IN, \*OUT, \*ERR, '/bin/cat'); # Doesn't work, either.

#Set IO to non-blocking. Makes it easier to get the error messages.
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);

$flags = fcntl(OUT, F_GETFL, 0)
or die "Can't get flags for the socket: $!\n";
$flags = fcntl(OUT, F_SETFL, $flags | O_NONBLOCK)
or die "Can't set flags for the socket: $!\n";
$flags = fcntl(ERR, F_GETFL, 0)
or die "Can't get flags for the socket: $!\n";
$flags = fcntl(ERR, F_SETFL, $flags | O_NONBLOCK)
or die "Can't set flags for the socket: $!\n";

# Set up select according to man IO::Select
$selectout = IO::Select->new(\*OUT, \*ERR ); # This doesn't work but
#$selectout = IO::Select->new(\*STDIN ); # ... this works as expected
$selectin = IO::Select->new(\*IN);
$selecterr = IO::Select->new(\*IN, \*OUT, \*ERR);

#while ($running) {
for (1..10) { # 10 loops are more than enough to show the problems
print "\nSelecting...";

# Select to get ready filehandles. The assignment sucks,
# but at least it should work
@myarr = IO::Select->select($selectin, $selectout, $selecterr, 10000);
@writers = @{$myarr[0]};
@readers = @{$myarr[1]};
@errors = @{$myarr[2]};

for $fh (@writers) {
print "Writing dummy to $$fh\n";
print $fh "dummy\n";
print "done\n";
}
for $fh (@readers) {
$rc = sysread($fh, $chunk, 2048); #XXX->future: call in loop
if ($rc) {
print "Read chunk from $$fh: <$chunk>\n";
} else {
print "Error while reading ($$fh): $!\n";
}
}
for $fh (@errors) {
print "Error in $$fh\n";
}

}



-- hello --


#!/usr/bin/perl -w
print "Name: \n";
$line = readline(STDIN);
for (1..10) { print "Hello $line"; }





--Ouput from asyn --
Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

Selecting...Error while reading (*main::ERR): Resource temporarily
unavailable
Error while reading (*main::OUT): Resource temporarily unavailable

--- Output from asyn if
$selectout = IO::Select->new(\*OUT, \*ERR ); # This doesn't work but
#$selectout = IO::Select->new(\*STDIN ); # ... this works as expected
are swapped --


En hest
Selecting...Read chunk from *main::STDIN: <En hest
>
^C



--
mvh. Esben Mose Hansen
homepage: www.mosehansen.dk --xxx-- GPG fingerprint:
www.mosehansen.dk/about.html

 
 
Esben Mose Hansen (24-12-2003)
Kommentar
Fra : Esben Mose Hansen


Dato : 24-12-03 13:53

Esben Mose Hansen wrote:

[...]

En løsning hedder Expect.pm, i hvert fald i Linux. Om det kan virke i
Windows finder jeg ud af efter jul.

Det ser ud til at Expect.pm benytter en tty-emulator til at gøre hvad den
gør --- så open3() var vist ikke vejen frem. Har dog ikke gravet i
Expect.pm...

--
mvh. Esben Mose Hansen
homepage: www.mosehansen.dk --xxx-- GPG fingerprint:
www.mosehansen.dk/about.html

Lars Balker Rasmusse~ (01-01-2004)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 01-01-04 17:21

Esben Mose Hansen <esben@despammed.com> writes:
> En løsning hedder Expect.pm, i hvert fald i Linux. Om det kan virke i
> Windows finder jeg ud af efter jul.
>
> Det ser ud til at Expect.pm benytter en tty-emulator til at gøre hvad den
> gør --- så open3() var vist ikke vejen frem. Har dog ikke gravet i
> Expect.pm...

Jeg skrev engang flg. til at skifte password via "passwd" kommandoen -
det er ca. det samme problem du har:

#!/usr/local/bin/perl -w

use strict;
use Expect;

my $pwd = "NYTPASSWORD";
my $command = "passwd";
my @params = ( "brugernavn" );

$Expect::Log_Stdout = 0;

my $exp = new Expect ($command, @params);
$exp->log_file(undef);

$exp->expect(undef,
[
qr/password:/ =>
sub { my $exp = shift;
$exp->send("$pwd\n");

exp_continue;
} ]
);

$exp->soft_close();
--
Lars Balker Rasmussen Consult::Perl

Esben Mose Hansen (02-01-2004)
Kommentar
Fra : Esben Mose Hansen


Dato : 02-01-04 16:57

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Lars Balker Rasmussen wrote:

> Esben Mose Hansen <esben@despammed.com> writes:
>> En løsning hedder Expect.pm, i hvert fald i Linux. Om det kan virke i
>> Windows finder jeg ud af efter jul.
>>
>> Det ser ud til at Expect.pm benytter en tty-emulator til at gøre hvad den
>> gør --- så open3() var vist ikke vejen frem. Har dog ikke gravet i
>> Expect.pm...
>
> Jeg skrev engang flg. til at skifte password via "passwd" kommandoen -
> det er ca. det samme problem du har:

[...]

Du har fuldstændigt ret, og tak :) Der er bare den lille detalje at windows
er noget hø --- så intet smart virker der. Heller ikke Expect.pm, og expert
(tcl) virker kun sporadisk. Trist, men sandt. Så jeg har blot indset at den
uge jeg brugte på det er spildt. Hey, jeg fik løn for det :)

- --
mvh. Esben Mose Hansen
homepage: www.mosehansen.dk --xxx-- GPG fingerprint:
www.mosehansen.dk/about.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/9ZTHrfnftt13wXIRAsVzAKCFlAHNlVXfvufggCXmpce1hBlHEACfU1a/
grSWXZvMN2byDya+vJU2u+Y=
=IuCX
-----END PGP SIGNATURE-----

Søg
Reklame
Statistik
Spørgsmål : 177428
Tips : 31962
Nyheder : 719565
Indlæg : 6407936
Brugere : 218877

Månedens bedste
Årets bedste
Sidste års bedste