1

我的任务是将站点镜像到新服务器上。旧网站有一些 Perl 脚本,据我在内部看到的(我对 Perl 一无所知,尽管我对编码有很好的理解,特别是 PHP/js/等)并不依赖于旧的服务器。也就是说,当我尝试运行此脚本时,该脚本会通过数据库文件查找适当的文章文件,但它不会检索任何内容。

基本上,这是一个基本的旧 CMS,正如我解释的那样,它在 PAG 文件中搜索文件名并显示它。我有点迷失在这里。镜像在新站点上不起作用是有原因的吗?我检查了权限,检查了 Perl 是否安装在相同的/usr/etc目录中。我认为它使用 dbm 因为,根据另一篇文章,如果我看到这样的命令:

 dbmopen( %ARTS, $art_dbm, 0644 );
 $entry = $ARTS{$article_id};
 dbmclose( %ARTS );

应该是dbm吧?

在相关说明中,是否有任何方法可以将该 PAG 文件的信息与原始文件合并,而无需极其复杂的 Perl 脚本;即,在文件本身中使用该信息重新创建 100 个文本文件,而不是单独存储?

编辑:感谢下面的第一个答案。你能解释一下 HASH 可能是什么,以及掩码吗?我已经仔细检查了 .pag 文件(数据库名称)确实位于之前在 .pl 文件中定义的位置,并且它是以二进制形式传输的。但不知何故我无法让它正确打开它!

编辑 3:好的,对不起,最后编辑在这里:我使用了下面的模具代码(Shwern),发现它没有找到那个数据库文件,尽管它在正确的目录中(两个文件articles.pag和articles.dir,但变量只引用没有扩展名的“文章”)并且拥有正确的权限......所以,现在的问题是到底发生了什么?这些是perl的不同版本吗?还是我只是在做一些基本而愚蠢的事情?郑重声明(是的,这很糟糕)我还没有 shell 访问权限,虽然我正在努力……我被要求这样做是因为我的“新网络”技能,我当然不合适perl 和 dbm 之类的人,虽然我可以阅读文件并理解它们。作为最后的建议,有谁知道如何(脚本等)我可以要求原始服务器人员(不是编码人员)对此进行 ASCII 转储,还是会不合时宜?我需要将它转换为 CSV 并返回到文件中,这样我就可以在另一个数据库中重用它……呃,真是一场噩梦!

4

3 回答 3

1

Do you still have access to the original machines?

Although you are using a DBM files, that actual functionality can come from one of several implementations, some of which are not compatible. I'd dump the file with the same perl that created it, then recreate it with the new perl.

于 2009-11-12T05:19:07.910 回答
1

如果我正确阅读了您的问题,那么您在新机器上打开数据库时会遇到困难。那里有数据库吗?

dbmopen 方法的文档可在命令行上通过perldoc -f dbmopen获得(以及在此链接中获取最新的稳定 perl 版本 5.10.1)。

正如您从文档中看到的那样,第二个参数dbmopen包含正在打开的文件名。在您粘贴的代码中,它包含在标量变量$art_dbm中。所以你需要做的是寻找这个变量的一些早期声明(也许它是从配置文件中加载的,或者它可能是硬编码的)。然后,一旦您找到了该数据库,只需将该文件传输到您的新机器上即可。

如果您在破译代码方面需要更多帮助,请随时使用代码片段编辑您的问题,我们可以从那里开始。

(现在,如果您找到了数据库但无法打开它,那么您遇到了其他问题。但是我已经很长时间没有处理 PAG 文件了。)

于 2009-11-11T23:11:20.693 回答
0

There's a few things which could be going wrong. The most obvious one is that the dbmopen() call isn't opening the file. If the DBM file doesn't exist, rather than failing dbmopen() just makes a new one which could be why it appears empty.

To eliminate that possibility, make sure the DBM file does exist and is readable. You also want to check if the dbmopen() succeeded, it will (usually) error out if its the wrong format.

die "$art_dbm does not exist" unless -e $art_dbm;
die "Cannot read $art_dbm"    unless -r $art_dbm;
dbmopen( %ARTS, $art_dbm, 0644 ) or die "dbmopen of $art_dbm failed: $!";

Unfortunately dbmopen() is too clever for its own good. If you give it "foo" it might create "foo.db" instead. Depends on the implementation. See below.

The other possibility is that your two Perls are trying to open the file with two different DBM implementations. Perl can be compiled with different sets of DBM implementations on your different machines. dbmopen() will use the first one in a hard coded (and historically barnacled) list. Its actually a wrapper around AnyDBM_File. You can check which implementation is being used with...

use AnyDBM_File;
print "@AnyDBM_File::ISA\n";

Make sure they're the same. If not, load the DBM library in question before using dbmopen. perldoc -f dbmopen explains.

Here's a demonstration. First we see what dbmopen() will default to.

$ perl -wle 'use AnyDBM_File; print "@AnyDBM_File::ISA"'
NDBM_File

Then create and populate a dbm file.

$ perl -wle 'dbmopen(%foo, "tmpdbm", 0644) or die $!; $foo{23} = 42;  print %foo'
2342

Now demonstrate we can read it.

$ perl -wle 'dbmopen(%foo, "tmpdbm", 0644) or die $!; print %foo'
2342

And try to read it using a different DBM implementation.

$ perl -wle 'use GDBM_File; dbmopen(%foo, "tmpdbm", 0644) or die $!; print %foo'

Nothing in the file, but no error either. Turns out it made a file called tmpdbm whereas ndbm was using tmpdbm.db. Let's try Berkeley DB.

$ perl -wle 'use DB_File; dbmopen(%foo, "tmpdbm", 0644) or die $!; print %foo'
Inappropriate file type or format at -e line 1.

At least that gives an error.

Your best bet is to figure out what DBM implementation the original machine is using and use that module before the dbmopen() call. That will make the situation static.

PS The Unix file utility will also give you a good idea what type of DBM it is.

$ file tmpdbm
tmpdbm: GNU dbm 1.x or ndbm database, little endian
$ file tmpdbm.db
tmpdbm.db: Berkeley DB 1.85 (Hash, version 2, native byte-order)

And hope to $diety its not a byte-order issue, less common now that almost everything is x86.

PPS As you can see, using DBM files is a bit of a mess. Strange considering its supposed to be just a hash-on-disk.

于 2009-11-12T05:19:23.493 回答