【问题标题】:moving a perl script/dbm to a new server, and shifting out of dbm?将 perl 脚本/dbm 移动到新服务器,并移出 dbm?
【发布时间】:2009-11-11 21:48:33
【问题描述】:

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

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

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

一定是dbm吧?

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

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

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

【问题讨论】:

    标签: database perl content-management-system mirroring dbm


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      你还能使用原来的机器吗?

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

      【讨论】:

        【解决方案3】:

        有一些事情可能会出错。最明显的一个是 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 文件有点混乱。奇怪的是它应该只是一个磁盘上的哈希。

        【讨论】:

          猜你喜欢
          • 2012-05-06
          • 1970-01-01
          • 2015-10-05
          • 2012-09-03
          • 1970-01-01
          • 1970-01-01
          • 2014-07-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多