将 perl 脚本/dbm 移动到新服务器,并移出 dbm?

发布于 2024-08-10 17:44:11 字数 1176 浏览 13 评论 0原文

我的任务是将站点镜像到新服务器上。旧站点有一些 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 个文本文件,而不是单独存储?

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

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

I've been tasked with mirroring a site onto a new server. The old site has a few Perl scripts that, as far as I can see internally (i know nothing about Perl, though I have a pretty good understanding of coding generally, and specifically PHP/js/etc) aren't reliant on the old server. That said, when I try to run this script, which looks through a database file to find the appropriate article file, it doesnt retrieve anything.

Basically, this is a rudimentary old CMS, as I explain it, where it searched the PAG file for the filename and displayed it. I am a little bit lost here. Is there a reason why the mirroring doesn't work on the new site? I've checked the permissions, I've checked that Perl is installed in the same /usr/etc directories. I think it uses dbm because, according to another article, if I see commands like these:

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

it must be dbm, right?

On a related note, is there any way to merge that PAG file's info with the original files without an incredibly sophisticated Perl script; i.e., recreate the 100 text files with that info in the file itself, rather than stored separately?

EDIT: thanks for the 1st answer below. can you explain what that HASH may be, and the mask? I've doublechecked that the .pag file (the database name) is indeed in the place where its defined earlier in the .pl file, and that it was transferred in binary. yet somehow I cant get it to open it correctly!

EDIT 3: Ok, sorry, final editing here: I used the die code below (Shwern) and found that it is not finding that DB file, despite it being there (two files articles.pag and articles.dir, but the variable only references "articles" without extensions) in the right directory and with the right permissions... So, the question here is now what the hell is going on? are these different versions of perl? or am i just doing something basic and stupid? for the record (yes, its terrible) i dont have shell access just yet, though i'm working on it... I was asked to do this because of my "new web" skills, and I'm certainly not the appropriate person for things like perl and dbm, though i can read the files and understand them. As a final suggestion, does anyone know how (a script or the like) I could ask the original server people (who are NOT the coders) to do an ASCII dump of this, or would that be out of line? I need to get this into CSV and back into the file so I can reuse it in another db... ugh what a nightmare!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪我太投入 2024-08-17 17:44:12

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

dbmopen 方法的文档可通过命令行 perldoc -f dbmopen (并在此链接获取最新的稳定 Perl 版本 5.10.1)。

正如您从文档中看到的,dbmopen 的第二个参数包含正在打开的文件名。在您粘贴的代码中,它包含在标量变量 $art_dbm 中。因此,您需要做的是查找该变量的一些早期声明(可能它是从配置文件加载的,或者可能是硬编码的)。然后,一旦您找到该数据库,所需要做的就是将该文件传输到您的新计算机。

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

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

If I read your question correctly, you're having difficulty opening the database on a new machine. Does the database exist there?

The documentation for the dbmopen method is available on the command line via perldoc -f dbmopen (and at this link for the latest stable perl release, 5.10.1).

As you can see from the docs, the second argument to dbmopen contains the filename being opened. In the code you pasted, that's contained in the scalar variable $art_dbm. So what you need to do is look for some earlier declaration of this variable (perhaps it is loaded in from a configuration file, or it could be hard-coded). Then once you've found that DB, all that should be necessary is transferring that file over to your new machine.

If you need more help deciphering the code, feel free to edit your question with a code snippet and we can go from there.

(Now, if you've found the database but you just can't open it, you've got some other problem.. It's been a long time since I dealt with PAG files however.)

鹿! 2024-08-17 17:44:12

您仍然可以使用原始机器吗?

尽管您使用的是 DBM 文件,但实际功能可能来自多种实现之一,其中一些实现不兼容。我将使用创建该文件的相同 perl 转储该文件,然后使用新的 perl 重新创建它。

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.

听闻余生 2024-08-17 17:44:12

有一些事情可能会出错。最明显的一个是 dbmopen() 调用没有打开文件。如果 DBM 文件不存在,dbmopen() 不会失败,只会创建一个新文件,这可能就是它显示为空的原因。

为了消除这种可能性,请确保 DBM 文件确实存在并且可读。您还想检查 dbmopen() 是否成功,如果格式错误,它(通常)会出错。

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: $!";

不幸的是 dbmopen() 太聪明了。如果您给它“foo”,它可能会创建“foo.db”。取决于实施。见下文。

另一种可能性是您的两个 Perls 正在尝试使用两种不同的 DBM 实现打开该文件。 Perl 可以在不同的机器上使用不同的 DBM 实现集进行编译。 dbmopen() 将使用硬编码(历史上是藤壶)列表中的第一个。它实际上是 AnyDBM_File 的包装。您可以检查正在使用哪个实现...

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

确保它们是相同的。如果没有,请在使用 dbmopen 之前加载有问题的 DBM 库。 perldoc -f dbmopen 解释。

这是一个演示。首先我们看看 dbmopen() 默认是什么。

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

然后创建并填充 dbm 文件。

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

现在证明我们可以阅读它。

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

并尝试使用不同的 DBM 实现来读取它。

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

文件中没有任何内容,但也没有错误。结果它创建了一个名为 tmpdbm 的文件,而 ndbm 使用的是 tmpdbm.db。让我们尝试一下 Berkeley DB。

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

至少这会产生错误。

最好的办法是弄清楚原始机器正在使用什么 DBM 实现,并在 dbmopen() 调用之前使用该模块。这将使情况变得静态。

PS Unix file 实用程序还可以让您很好地了解它是什么类型的 DBM。

$ 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)

希望 $diety 这不是一个字节顺序问题,现在几乎所有东西都是 x86,所以不太常见。

PPS 正如您所看到的,使用 DBM 文件有点混乱。奇怪的是,考虑到它应该只是磁盘上的哈希。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文