Есть несколько вещей, которые могут пойти не так. Наиболее очевидным является то, что вызов 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";
Убедитесь, что они одинаковы. Если нет, загрузите соответствующую библиотеку DBM перед использованием dbmopen. 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. Давайте попробуем Беркли 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 немного беспорядочно. Странно, учитывая, что он должен быть просто хешем на диске.