[SP-pm] Perl para automação em acesso a x3270 IBM

Marcio - Google marciorp at gmail.com
Thu Jul 12 19:15:23 PDT 2012


Em 12 de julho de 2012 09:30, Eden Cardim <edencardim em gmail.com> escreveu:
>>>>>> "Marcio" == Marcio  <- Google <marciorp em gmail.com>> writes:
>
>     Marcio> Olá Prof. Eden,
>     Marcio> Montei esse primeiro exemplo, tipo "Olá mundo!", mais esbarrei em um
>     Marcio> erro que não consigo resolver.
>
>     Marcio> #!/usr/bin/perl
>
>     Marcio> use strict;
>     Marcio> use warnings;
>     Marcio> use Expect;
>
>     Marcio> my $exp = Expect->spawn('s3270');
>
>     Marcio> $exp->log_file('/home/marcio/teste3.log');
>
>     Marcio> my $cmd1 = "connect(10.1.8.192:23)\n";
>     Marcio>    $cmd1 .= "wait(InputField)\n";
>
>     Marcio> $exp->send($cmd1);
>     Marcio> $exp->expect(100, [qr/.{1920}/ => sub {
>     Marcio>                                          my($self) = @_;
>     Marcio>                                          print $self->match;
>
>     Marcio>                                          exp_continue;
>     Marcio>                                       },
>     Marcio>                    timeout => sub { die 'o sistema parou de responder' }
>     Marcio>                   ]
>     Marcio>             )
>
>     Marcio> Roda certinho, pelo menos não dá erro nenhum, o problema é que como se
>     Marcio> no lugar do "\n" no final dos comandos, ele trocasse por "^M", e ai dá
>     Marcio> erro no s3270. No mesmo exemplo usando o IPC::Run não acontece isso.
>
> Tem certeza que é o *mesmo* exemplo? Posta aí pra gente ver. Esses "^M"
> são da codificação do seu terminal local. Se fosse um problema pro s3270
> você não veria nada no output.
>

Olá o código ai, é o mesmo exemplo só que usando o IPC::Run. Por
desencargo, rodei os dois agora a pouco novamente, e mesma coisa. Com
o Expect dá erro, e com o IPC:Run não.

#!/usr/bin/perl

my @s3270 = s3270;

use IPC::Run qw( start pump finish timeout );
$IPCRUNDEBUG=details;

my $h = start \@s3270, \$in, \$out, \$err, timeout( 100 );

$in .= "connect(10.1.8.192:23)\n";
$in .= "wait(InputField)\n";

finish $h or die "s3270 returned $?";

warn $err if $err;
print $out;


Saída no terminal:

U U U C(10.1.8.192) I 4 43 80 0 0 0x0 0.167
ok
U F U C(10.1.8.192) I 4 24 80 15 34 0x0 -
ok


>     Marcio> Veja a saída no terminal:
>
>     Marcio> connect(10.1.8.192:23)^M
>     Marcio> wait(InputField)^M
>     Marcio> L U U N N 4 24 80 0 0 0x0 0.024^M
>     Marcio> error^M
>     Marcio> data: Wait: Not connected^M
>     Marcio> L U U N N 4 24 80 0 0 0x0 -^M
>     Marcio> error^M
>
>     Marcio> E o arquivo de log (/home/marcio/teste3.log):
>
>     Marcio> connect(10.1.8.192:23)^M
>     Marcio> wait(InputField)^M
>     Marcio> L U U N N 4 24 80 0 0 0x0 0.026
>     Marcio> error
>     Marcio> data: Wait: Not connected
>     Marcio> L U U N N 4 24 80 0 0 0x0 -
>     Marcio> error
>
>     Marcio> Tem alguma ideia?
>
> Bom, é difícil depurar à distância asssim. Me parece que o erro não tem
> nada a ver com o \n, o que está acontecendo é que o terminal do outro
> lado está esperando mais input e você não está fornencendo, por isso dá
> erro. Eu não entendo nada de TN3270 mas geralmente esses terminais mais
> antigos precisam negociar o encerramento da conexão.

Na verdade não sou especialista também, mais ele processa cada linha
como um comando individual, e no exemplo ai o primeiro é para conectar
no host. Quando eu rodo ele no modo interativo, onde vou digitando os
comando, no final de cada linha teclo <ENTER> e ele processa o
comando. No script o \n faz a função de teclar o <ENTER> no modo
interativo.

>
>     Marcio> Em tempo, essa expressão (qr/.{1920}/) pega o retorno com
>     Marcio> 1920 caracteres. Vou colocar várias expressões, agora como
>     Marcio> faço uma tipo "default", se não casar com nenhuma das
>     Marcio> anteriores cai nessa última?
>
> Sim, e já está aí no exemplo: é o timeout => sub {} faz isso. Essa
> subroutina roda se passar o tempo que você especificou (nesse caso, 100
> segundos) e a saída não casar com nenhuma das expressões.

Então, isso que não entendi. Se o retorno não casar com nenhuma
expressão ele vai cair aqui, mais só depois de ocorrer o timeout, ou
seja, mesmo que ocorra algum retorno, ele só vai processar depois de
100 segundos (ou o que eu definir). É isso? Se for, volta a pergunta,
tem como colocar uma expressão default que seja processada antes do
timeout se nenhuma das outras casar?

>
>     Marcio> Desculpe a lerdeza, mais é que como disse não sou
>     Marcio> programador, tó quebrando um galho para resolver um problema
>     Marcio> do meu sistema Asterisk.
>
> Não precisa se desculpar em todos os posts, nós já entendemos ;)

É que fico até constrangido fazendo perguntas tão banais a mestres ... :-)
Brinco com microcontroladores (eletrônica) por hobby, e a coisa mais
difícil e conseguir ajuda de algum expert/engenheiro nos fóruns
especializados da areá. Os kras se consideram superiores, e nunca
foram aprendizes e tiveram dúvidas.

>
> O problema agora tem mais a ver com o entendimento do funcionamento do
> TN3270 do que com programação. A única referência a respeito disso que
> eu encontrei foi isso aqui: http://ibm.co/PSEH13

Então, para mim o TN3270 não tem muito mistério ou o que mexer, pois
quando eu conecto eu já caio em uma tela da aplicação e a partir dai é
digitar usuário/senha e ir selecionando opções no menus e depois
digitando e lendo dados. Eu não uso comandos e outros recursos.
Quando conecto pelo s3270 no modo interativo ou mesmo o c3270, eu
consigo fazer todas as operações necessárias.
Outro detalhes é que o exemplo com o IPC::Run funcionou, então não
pode ser alguns detalhe do Expect?
Pelo que eu andei lendo da documentação, to achando que o Expect é
mesmo a melhor opção em relação ao IPC::Run. Desculpa Nelson ... :-)

>
> Boa sorte

Obrigado, to precisando ... ;-)

>
> --
> Eden Cardim
> +55 11 9644 8225

Abs,

Marcio.


More information about the SaoPaulo-pm mailing list