我之前从未使用过Perl,但是一个旧脚本需要进行一些更改(现在正成为处理的负担)。
情景:
将文本推送到脚本STDIN
./ myscript.pl<文本
该文本有以下几行(其中包括):
...
To: "" <myemail@domain.com>
...
Type *123 to access this file.
...
我需要做的是将myemail@domain.com分配给variable1,将123分配给variable2,然后执行一个MySQL选择,它将根据前两个返回variable3。
我有:
$line = <>;
my ($email) = ($line =~ m/To: ".*" <(.*)>/);
my ($num) = ($line =~ m/*.\*(\d+) .*$);
#Connect to the database
my $dbh = DBI->connect('DBI:mysql:dbase:localhost:3306', 'dbun', 'dbpass')
or die "Couldn't open database: $DBI::errstr; stopped";
# Fetch each row and print it
my ($enabled) = $dbh->selectrow_array(SELECT myfield FROM mydb WHERE mynum = "$num" and email = "$email");
# Disconnect from the database
$dbh->disconnect();
if($enabled eq "no") {
die "Not enabled";
}
...
然而这不起作用。
我做错了什么?
更新
以下是我提到的修订后的内容。从数据库成功获取变量,但如果“enabled”设置为“no”,则无法退出脚本。由于某种原因,查询是循环的。
#!/usr/bin/perl
use warnings;
use diagnostics;
use DBI;
use DBD::mysql;
open(STDOUT, '>', '/var/log/vm/vm2email.out') or die "Can't open log";
open(STDERR, '>', '/var/log/vm/vm2email.log') or die "Can't open log";
open(VOICEMAIL,"|/usr/sbin/sendmail -t");
open(LAMEDEC,"|/usr/bin/dos2unix|/usr/bin/base64 -di|/usr/bin/lame --quiet --preset voice - /var/spool/asterisk/tmp/vmout.$$.mp3");
open(VM,">/var/spool/asterisk/tmp/vmout.debug.txt");
my $inaudio = 0;
my $email;
my $ext;
loop: while(<>){
if(/^\.$/){
last loop;
}
if(/^Content-Type: audio\/x-wav/i){
$inaudio = 1;
}
if (/To: ".*" <(.*)>/ ) {
$email = $1;
print "$email\n";
}
if (/\*(\d+) / ) {
$ext = $1;
print "$ext\n";
}
if ( $email && $ext ) {
# Connect to the database
$dbh = DBI->connect('DBI:mysql:mydb:localhost:3306', 'dbun', 'dbpass')
|| die "Couldn't open database: $DBI::errstr; stopped";
$enabled = $dbh->selectrow_array('SELECT sendvoicemail FROM data_voicemail WHERE vmbox = ? and email = ?', {}, $ext, $email)
|| die "Couldn't get DB value, stopped";
}
if ($enabled eq "no"){
last;
}
if($inaudio){
while(s/^(Content-.*)wav(.*)$/$1mp3$2/gi){}
if(/^\n$/){
iloop: while(<>){
print LAMEDEC $_;
if(/^\n$/){
last iloop;
}
}
close(LAMEDEC);
print VOICEMAIL "\n";
print VM "\n";
open(B64,"/usr/bin/base64 /var/spool/asterisk/tmp/vmout.$$.mp3|");
while(<B64>){
print VOICEMAIL $_;
print VM $_;
}
close(B64);
print VOICEMAIL "\n";
print VM "\n";
$inaudio = 0;
}
}
print VOICEMAIL $_;
print VM $_;
}
print VOICEMAIL "\.";
print VM "\.";
close(VOICEMAIL);
close(VM);
答案 0 :(得分:1)
你没有说出了什么问题。
我确实看到你没有引用你的sql字符串,这会导致语法错误;尝试
my ($enabled) = $dbh->selectrow_array('SELECT myfield FROM mydb WHERE mynum = "$num" and email = "$email"');
虽然您应该避免将用户输入直接放入sql并改为使用占位符:
my ($enabled) = $dbh->selectrow_array('SELECT myfield FROM mydb WHERE mynum = ? and email = ?', {}, $num, $email);
在尝试提取值时,您还有三个问题。
首先,在尝试使用您获得的值之前,您没有验证正则表达式是否成功。
其次,$num
正则表达式是错误的。我认为你的意思是做/.*\*(\d+) .*$/
,但/\*(\d+)/
将是一个更简单的正则表达式,完全相同。
第三,如果你想要的值在不同的行上,你需要在循环中一次提取一个:
my $email;
my $num;
while ( my $line = <> ) {
if ( $line =~ m/To: ".*" <(.*)>/ ) {
$email = $1;
}
if ( $line =~ /\*(\d+) / ) {
$num = $1;
}
}
if ( $email && $num ) {
# database query here
}
(除非您将整个文件作为单个字符串读入)。