2015-01-11 4 views
0

Я искал сценарий Perl, который неожиданно висел, когда он никогда не висел раньше. Я не знаю Perl. Я, наконец, проследил проблему до строки пути к файлу. Этот код работает:Почему подчеркивание в имени пути заставляет скрипт Perl зависать?

$eng_morph = "~/datafile.en.db"; 
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph"; 

Когда я изменить имя файла, чтобы включить подчеркивание, то вторая линия висит навсегда:

$eng_morph = "~/datafile.en_us.db"; 
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph"; 

Есть ли что-то не так с синтаксисом? Есть ли способ разрешить подчеркивание?

Я использую Ubuntu 14.04. Вот вывод uname:

Linux-ноутбук ASUS 3.13.0-43-родовое # 72-Ubuntu SMP пн 8 декабря 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Кроме того, я также использую по умолчанию Perl в дистрибутиве. Его версия выход:

Это Perl 5, версия 18, подрывная 2 (v5.18.2), построенный для x86_64-Linux-гну-нить-мульти (с 41 зарегистрированных пластырей см Perl -V для более подробно)

+4

ваш код имеет несвязанную ошибку: '||' должен быть 'или'. '||' имеет высокий приоритет, поэтому вместо того, чтобы угасать при сбое связи, он умирает, когда 0664 является ложным (это никогда) – ysth

+0

@ysth - это может быть не «несвязанным». Возможно, эта ошибка маскирует реальную проблему, а «умирающая часть» никогда не умирает. Я не знаком с Perl и не понимаю синтаксис вашей коррекции. Не могли бы вы поместить полную коррекцию в ответ, чтобы я мог попробовать? – tahoar

ответ

0

Эта проблема была прерывистой. Это оказалось проблемой с потоками - так много проблем. Подсказка заключалась в наличии нечетного файла в выходной папке: "~/_db_datafile.en.db" ... или любое определенное имя выходного файла с префиксом "~/_db_". Этот выходной файл находился в диапазоне от 0 до 14 Кбайт, когда требуемый выходной файл должен был быть 2 или 3 мегабайта.Похоже, функция Perl tie() была прервана при создании файла DB.

Этот код вызывался из сценария Python, который использовал неблокирующие потоки с использованием подпроцесса .Popen(). Сценарий Python породил скрипт Perl и продолжил поток. Хотя скрипт Perl все еще создавал файл базы данных, незаблокированный поток Python запускал данные о трубопроводах. Это остановило создание файла сценария Perl и вызвало блокировку.

Подчеркивание в имени файла было только первым прерывистым экземпляром этой ошибки и в конечном итоге не имело отношения к проблеме.

Разрешение было просто создать цикл while not os.path.exists(eng_morph): в коде Python для приостановки до тех пор, пока не появится соответствующий файл DB.

1

Существует почти что-то неправильно с этим конкретным файлом DB, а не с именем файла.

Либо файл DB поврежден каким-то образом, либо существующий процесс на сервере открывает файл и заблокировал его.

Посмотрите, открыт ли какой-либо другой файл (с использованием lsof) и проверьте файлы, похожие на базу данных, но начиная с "." в том же каталоге. (То есть сделать ls -a ~ | grep -i en_us)

+0

Невозможно быть поврежденным файлом DB, потому что выходная папка создается специально для этого вывода. Затем код Perl создает файл DB в пустой выходной папке. Однако я согласен, что это не подчеркивание. Проблема блокировки, наконец, произошла с именем файла без подчеркивания. – tahoar

1
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph"; 

должно быть:

tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664 or die "Cannot open dbmfile $eng_morph"; 

или

tie(%eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664) || die "Cannot open dbmfile $eng_morph"; 

, потому что || высокий приоритет операторов. В противном случае он интерпретируется как:

tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, (0664 || die "Cannot open dbmfile $eng_morph"); 

|| предназначен для естественно использовать в выражении, который возвращает результат; or предназначен для управления потоком между существенно отличающимися выражениями (хотя они отличаются только приоритетом).

Из-за этой ошибки, когда связь завершается с ошибкой, вы не умираете, и код продолжает работать, но оставляя% eng_morph как обычный, развязанный хеш.

+0

Спасибо, ysth. Я обновил код, но он не разрешил зависание или не обнаружил основную ошибку. Я, однако, нашел проблему и написал свой собственный ответ. – tahoar