我是perl的新手但是了解C和C ++。我想将以下url下的perl脚本转换为shell或bash: https://code.google.com/p/busware/source/browse/trunk/SD0/Firmware_VZ/vzfeeder/vzfeeder.pl
以下是代码:
#!/usr/bin/perl
use warnings;
use strict;
use Time::HiRes qw/ gettimeofday /;;
use POE;
use POE::Wheel::ReadWrite;
use POE::Wheel::ReadLine;
use POE::Component::Client::HTTP;
use POE::Component::DBIAgent;
use Symbol qw(gensym);
use Device::SerialPort;
use POE::Filter::Line;
use HTTP::Request;
use Data::Dumper;
use DateTime;
sub DB_NAME () { "volkszaehler" }
sub DB_USER () { "vz" }
sub DB_PASS () { "demo" }
use Log::Log4perl qw/:easy/;
Log::Log4perl->easy_init( {
level => $INFO,
layout => '[%d] %p %c - %m%n',
} );
INFO('starting logger process');
POE::Session->create(
inline_states => {
_start => \&setup_device,
open_serial => \&open_serial,
program_serial => \&program_serial,
got_serial => \&got_serial,
got_error => \&handle_errors,
cmd_V => \&got_version,
cmd_L => \&got_portbits,
queue_cmd => \&queue_cmd,
mod_reset => \&mod_reset,
mod_bl => \&mod_bl,
query_all_channels_done => \&handle_query_all_channels_response,
finish_query_all_channels => \&finish_query_all_channels,
},
)->option( trace => 1 );
POE::Kernel->run();
exit 0;
sub setup_device {
my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
POE::Component::Client::HTTP->spawn(
Alias => 'ua',
Timeout => 10,
);
INFO('opening database link');
my $dbi = $heap->{dbi_helper} = POE::Component::DBIAgent->new(
DSN => ['dbi:mysql:dbname=' . DB_NAME, DB_USER, DB_PASS],
Count => 3,
Queries => {
query_all_channels => 'select * from entities',
insert_tickdata => 'insert into data (timestamp,channel_id,value) values (?, ?, ?)',
# update => "update test set value = ? where name = ?",
# delete => "delete from test where name = ?",
},
);
$heap->{CHANNELS} = [];
$dbi->query(query_all_channels => $session->ID => 'query_all_channels_done');
$kernel->yield( 'open_serial' );
}
# open serial Port
sub open_serial {
my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0];
INFO('opening serial port');
qx^if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi^;
qx^echo out > /sys/class/gpio/gpio27/direction^;
qx^echo 1 > /sys/class/gpio/gpio27/value^;
qx^if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi^;
qx^echo out > /sys/class/gpio/gpio17/direction^;
qx^echo 0 > /sys/class/gpio/gpio17/value^;
qx^echo 1 > /sys/class/gpio/gpio17/value^;
# Open a serial port, and tie it to a file handle for POE.
my $handle = gensym();
my $port = tie(*$handle, "Device::SerialPort", "/dev/ttyAMA0");
die "can't open port: $!" unless $port;
$port->datatype('raw');
$port->reset_error();
$port->baudrate(38400);
$port->databits(8);
$port->parity('none');
$port->stopbits(1);
$port->handshake('none');
$port->write_settings();
$port->lookclear();
# Start interacting with the GPS.
$heap->{port} = $port;
$heap->{port_wheel} = POE::Wheel::ReadWrite->new(
Handle => $handle,
Filter => POE::Filter::Line->new(
InputLiteral => "\x0D\x0A", # Received line endings.
OutputLiteral => "\x0D", # Sent line endings.
),
InputEvent => "got_serial",
ErrorEvent => "got_error",
);
$kernel->delay_add( queue_cmd => 2 => 'v' );
$kernel->delay( program_serial => 5 );
}
# programming via serial Port
sub program_serial {
my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0];
INFO('flashing module @ serial port');
delete $heap->{port_wheel};
untie( $heap->{port} ) if $heap->{port};
delete ( $heap->{port} );
qx^if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi^;
qx^echo out > /sys/class/gpio/gpio17/direction^;
qx^echo 0 > /sys/class/gpio/gpio17/value^;
qx^if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi^;
qx^echo out > /sys/class/gpio/gpio27/direction^;
qx^echo 0 > /sys/class/gpio/gpio27/value^;
qx^echo 1 > /sys/class/gpio/gpio17/value^;
qx^sleep 1^;
qx^echo 1 > /sys/class/gpio/gpio27/value^;
qx^avrdude -p atmega1284p -P /dev/ttyAMA0 -b 38400 -c avr109 -U flash:w:main.hex^;
$kernel->yield( 'open_serial' );
}
# Port data (lines, separated by CRLF) are displayed on the console.
sub got_serial {
my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0];
INFO( 'got_serial: ' . $data );
my @v = split( /\s+/, $data );
# Channel ticks?
if ($v[0] =~ /^([ABCD])$/) {
my $ch = $1;
INFO( 'Tick @ ' . $ch );
my ($seconds, $microseconds) = gettimeofday;
my $sec = sprintf( '%d%03d', $seconds, $microseconds/1000 );
$heap->{dbi_helper}->query( insert_tickdata => $session->ID => undef => ($sec, ord($ch)-64, 1));
return;
}
my $cmd = sprintf 'cmd_%s', shift @v;
$kernel->yield( $cmd => [@v] );
}
# Error on the serial port. Shut down.
sub handle_errors {
my $heap = $_[HEAP];
ERROR( 'received error!' );
delete $heap->{port_wheel};
}
sub got_version {
my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0];
INFO( 'VERSION: ' . $data->[0] );
$heap->{VERSION} = $data->[0];
$kernel->delay( 'program_serial' );
}
sub got_portbits {
my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0];
INFO( 'Portbits: ' . $data->[0] );
$heap->{PORTBITS} = $data->[0];
}
sub queue_cmd {
my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0];
$heap->{port_wheel}->put( $data );
}
#
# DATABASE work
#
sub handle_query_all_channels_response {
my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0];
if (ref($data) eq 'ARRAY') {
push $heap->{CHANNELS}, $data;
} elsif ($data eq 'EOF') {
$kernel->yield( finish_query_all_channels => $heap->{CHANNELS} );
}
}
sub finish_query_all_channels {
my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0];
INFO( Dumper($heap->{CHANNELS}));
}
以下是perl脚本的一部分,如shell / bash:
#!/usr/bin/sh
function setup_device() {{
}
function open_Serial(){
echo "opening serial port; Resetting\\Booting the SD0"
if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi
echo out > /sys/class/gpio/gpio27/direction
echo 1 > /sys/class/gpio/gpio27/value
if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi
echo out > /sys/class/gpio/gpio17/direction
echo 0 > /sys/class/gpio/gpio17/value
echo 1 > /sys/class/gpio/gpio17/value
minicom -b 38400 -o -D /dev/ttyAMA0
}
function program_Serial(){
echo "flashing module @ serial port"
echo calling co-processor bootloader ...
if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi
echo out > /sys/class/gpio/gpio17/direction
echo 0 > /sys/class/gpio/gpio17/value
if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi
echo out > /sys/class/gpio/gpio27/direction
echo 0 > /sys/class/gpio/gpio27/value
echo 1 > /sys/class/gpio/gpio17/value
sleep 1
echo 1 > /sys/class/gpio/gpio27/value
avrdude -p atmega1284p -P /dev/ttyAMA0 -b 38400 -c avr109 -U flash:w:SD0.hex
}
例如
my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0];
意思?我为函数(?)提供了参数,但是如何转换ARG? 或者下面的代码是做什么的?
my $handle = gensym();
是否有工具将perl脚本转换为shell?或者(好的Doc)可以帮助翻译?
答案 0 :(得分:5)
您的Perl程序是围绕POE (the Perl Object Environment)构建的,这是一种事件循环机制,允许并行执行多个独立任务以响应事件,消息或已用时间。它是一套全面的模块,与其他语言相对应,但不能直接复制到任何地方
例如
my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0];
意思?我为函数(?)提供了参数,但是如何转换ARG?
这是POE
调用机制的一部分。参数传递给@_
数组中的Perl子例程,POE
有一个约定,即相同的参数总是以相同的顺序传递给它的成员子例程。值KERNEL
,HEAP
等只是数字常量,用于将索引标记到参数列表中。例如SESSION
,KERNEL
和HEAP
分别为1,2和3。 ARG0
为10,因此它选择了@_
的第11个元素。其他值已定义
或者下面的代码在做什么?
my $handle = gensym();
这是Perl的一个非常深奥的角落。 gensym
由Symbol
module提供,在这种情况下,它是一种创建文件句柄而不为其提供特定标识符的方法
是否有工具将perl脚本转换为shell?或者(好的Doc)可以帮助翻译?
没有任何东西可以将一般的Perl程序转换为任何其他语言,因为正如我在上面的评论中暗示的那样,Perl有一种独特的方式来交织编译和执行阶段,这是其他语言所没有的。可能会有一些东西可以转换非常基本的Perl,但我没有遇到它,无论如何你的代码不符合 basic