Spec-Zone.ru › Perl 5.30

perlport

СОДЕРЖАНИЕ

  • ИМЯ
  • ОПИСАНИЕ
  • ПРОБЛЕМЫ
    • Новые строки
    • Порядок байтов и ширина чисел
    • Файлы и файловые системы
    • Взаимодействие с системой
    • Имена команд против путей к файлам
    • Сеть
    • Межпроцессное взаимодействие (IPC)
    • Внешние подпрограммы (XS)
    • Стандартные модули
    • Время и дата
    • Наборы символов и кодировка символов
    • Международная поддержка
    • Системные ресурсы
    • Безопасность
    • Стиль
  • Тестеры CPAN
  • ПЛАТФОРМЫ
    • Unix
    • DOS и производные
    • VMS
    • VOS
    • Платформы EBCDIC
    • Acorn RISC OS
    • Другие Perl-системы
  • РЕАЛИЗАЦИИ ФУНКЦИЙ
    • Алфавитный список функций Perl
  • Поддерживаемые платформы
  • Платформы с окончанием срока службы
    • Perl 5.20
    • Perl 5.14
    • Perl 5.12
  • Поддерживаемые платформы (Perl 5.8)
  • СМОТРИТЕ ТАКЖЕ
  • АВТОРЫ/СОТРУДНИКИ

ИМЯ

perlport - Написание переносимого Perl

ОПИСАНИЕ

Perl работает на многочисленных операционных системах. Хотя большинство из них имеют много общего, у них также есть свои уникальные особенности.

Этот документ призван помочь вам понять, что составляет переносимый код Perl. Таким образом, приняв решение о написании переносимого кода, вы знаете, где проходят границы, и можете оставаться в их пределах.

Существует компромисс между полным использованием одного конкретного типа компьютера и использованием всего спектра компьютеров. Естественно, по мере расширения диапазона и увеличения разнообразия общие факторы уменьшаются, и вы остаетесь с всё более уменьшающейся областью общих возможностей для выполнения конкретной задачи. Таким образом, приступая к решению проблемы, важно учитывать, на какой части кривой компромисса вы хотите работать. В частности, вы должны решить, важно ли, чтобы задача, которую вы программируете, имела полную переносимость, или достаточно выполнить задачу прямо сейчас. Это самый трудный выбор. Остальное легко, потому что Perl предоставляет много вариантов, какой бы подход вы ни выбрали к своей задаче.

Другими словами, написание переносимого кода обычно подразумевает преднамеренное ограничение доступных вариантов. Естественно, это требует дисциплины и жертв. Продукт переносимости и удобства может быть постоянной величиной. Вас предупредили.

Обратите внимание на два важных момента:

Не все программы Perl должны быть переносимыми

Нет причин не использовать Perl в качестве языка для связывания утилит Unix или прототипирования приложения для Macintosh или управления реестром Windows. Если по какой-либо причине в данной программе нет смысла стремиться к переносимости, то не стоит этого делать.

Практически весь Perl уже является переносимым

Не думайте, что создание переносимого кода Perl сложно. Это не так. Perl старается максимально устранить различия между платформами, и предоставляет все средства для использования этих особенностей. Таким образом, почти весь код Perl работает на любом компьютере без изменений. Но существуют некоторые значительные проблемы при написании переносимого кода, и этот документ целиком посвящен этим проблемам.

Вот общее правило: когда вы решаете задачу, обычно выполняемую на широком спектре платформ, подумайте о написании переносимого кода. Таким образом, вы не сильно жертвуете в плане выбора реализаций, и в то же время вы можете дать своим пользователям множество вариантов платформ. С другой стороны, когда вам необходимо использовать уникальные особенности какой-либо конкретной платформы, как это часто бывает при системном программировании (будь то для Unix, Windows, VMS и т. д.), подумайте о написании платформенно-специфического кода.

Если код будет работать только на двух-трёх операционных системах, вам, возможно, потребуется учитывать только различия этих конкретных систем. Важно решить, где будет работать код, и принять обдуманное решение.

Материал ниже разделен на три основных раздела: основные проблемы переносимости (ПРОБЛЕМЫ), платформенно-специфические проблемы (ПЛАТФОРМЫ) и встроенные функции Perl, поведение которых отличается на различных портах (РЕАЛИЗАЦИИ ФУНКЦИЙ).

Эта информация не должна рассматриваться как полная; она включает, возможно, временную информацию об особенностях некоторых портов, практически все из которых постоянно эволюционируют. Таким образом, этот материал следует рассматривать как постоянно развивающийся проект (<IMG SRC="yellow_sign.gif" ALT="Under Construction">).

ПРОБЛЕМЫ

Новые строки

В большинстве операционных систем строки в файлах завершаются новой строкой. Именно что используется в качестве новой строки может варьироваться от одной ОС к другой. Unix традиционно использует \012, один тип ввода/вывода DOS использует \015\012, Mac OS использует \015, а z/OS использует \025.

Perl использует \n для представления "логической" новой строки, где то, что является логическим, может зависеть от используемой платформы. В MacPerl \n всегда означает \015. На платформах EBCDIC \n может быть \025 или \045. В Perl-системах, подобных DOS, \n обычно означает \012, но при обращении к файлу в режиме "текст" perl использует слой :crlf, который преобразует его в (или из) \015\012, в зависимости от того, читаете вы или пишете. Unix делает то же самое для tty в каноническом режиме. \015\012 обычно называют CRLF.

Для обрезки конечных новых строк из строк текста используйте chomp. С настройками по умолчанию эта функция ищет конечный символ \n и, таким образом, обрезает его переносимым способом.

При работе с двоичными файлами (или текстовыми файлами в двоичном режиме) убедитесь, что явно установили $/ в соответствующее значение для вашего формата файла перед использованием chomp.

Из-за преобразования в режиме "текст" у DOS-подобных Perl есть ограничения при использовании seek и tell с файлом, доступным в режиме "текст". Придерживайтесь seek до положений, полученных от tell (и никаких других), и вы обычно можете использовать seek и tell даже в режиме "текст". Использование seek или tell или других операций с файлами может быть не переносимым. Однако, если вы используете binmode с файлом, вы обычно можете seek и tell с произвольными значениями безопасно.

Распространённое заблуждение в программировании сокетов заключается в том, что \n eq \012 везде. При использовании таких протоколов, как общие интернет-протоколы, \012 и \015 требуются специально, и значения логических \n и \r (возврат каретки) ненадёжны.

print $socket "Hi there, client!\r\n";      # WRONG
print $socket "Hi there, client!\015\012";  # RIGHT

Однако, использование \015\012 (или \cM\cJ, или \x0D\x0A) может быть утомительным и некрасивым, а также сбивающим с толку для тех, кто поддерживает код. В связи с этим, модуль Socket предоставляет необходимое решение для тех, кто этого хочет.

use Socket qw(:DEFAULT :crlf);
print $socket "Hi there, client!$CRLF"      # RIGHT

При чтении из сокета помните, что по умолчанию разделитель записей ввода $/ равен \n, но надёжный код сокетов распознаёт \012 или \015\012 как конец строки:

while (<$socket>) {  # NOT ADVISABLE!
    # ...
}

Поскольку оба CRLF и LF заканчиваются LF, разделитель записей ввода можно установить на LF, а любые CR удалить позже. Лучше написать:

use Socket qw(:DEFAULT :crlf);
local($/) = LF;      # not needed if $/ is already \012

while (<$socket>) {
    s/$CR?$LF/\n/;   # not sure if socket uses LF or CRLF, OK
#   s/\015?\012/\n/; # same thing
}

Этот пример предпочтительнее предыдущего, даже для платформ Unix, потому что теперь любые \015 (\cM's) удаляются (и тут было много радости).

Аналогично, функции, возвращающие текстовые данные (например, функция, получающая веб-страницу), иногда должны преобразовывать новые строки перед возвратом данных, если они ещё не преобразованы в локальное представление новой строки. Обычно достаточно одной строки кода:

$data =~ s/\015?\012/\n/g;
return $data;

Некоторые моменты могут быть непонятны. Вот полезная справка по ASCII-символам CR и LF. Вы можете распечатать её и положить в бумажник.

LF  eq  \012  eq  \x0A  eq  \cJ  eq  chr(10)  eq  ASCII 10
CR  eq  \015  eq  \x0D  eq  \cM  eq  chr(13)  eq  ASCII 13

         | Unix | DOS  | Mac  |
    ---------------------------
    \n   |  LF  |  LF  |  CR  |
    \r   |  CR  |  CR  |  LF  |
    \n * |  LF  | CRLF |  CR  |
    \r * |  CR  |  CR  |  LF  |
    ---------------------------
    * text-mode STDIO

Столбец Unix предполагает, что вы не обращаетесь к последовательному каналу (например, tty) в каноническом режиме. Если вы это делаете, то CR на входе становится «\n», а «\n» на выходе становится CRLF.

Это лишь наиболее распространённые определения \n и \r в Perl. Возможно, есть и другие. Например, на реализации EBCDIC, такой как z/OS (OS/390) или OS/400 (использующей ILE, PASE основана на ASCII), вышеуказанный материал аналогичен «Unix», но изменяются кодовые числа:

LF  eq  \025  eq  \x15  eq  \cU  eq  chr(21)  eq  CP-1047 21
LF  eq  \045  eq  \x25  eq           chr(37)  eq  CP-0037 37
CR  eq  \015  eq  \x0D  eq  \cM  eq  chr(13)  eq  CP-1047 13
CR  eq  \015  eq  \x0D  eq  \cM  eq  chr(13)  eq  CP-0037 13

         | z/OS | OS/400 |
    ----------------------
    \n   |  LF  |  LF    |
    \r   |  CR  |  CR    |
    \n * |  LF  |  LF    |
    \r * |  CR  |  CR    |
    ----------------------
    * text-mode STDIO

Числа, порядок байтов и ширина

Разные процессоры хранят целые числа и числа с плавающей точкой в разных порядках (называемых порядком байтов) и ширинах (32-битные и 64-битные являются наиболее распространёнными сегодня). Это влияет на ваши программы, когда они пытаются передавать числа в двоичном формате от одной архитектуры процессора к другой, обычно либо «в реальном времени» через сетевое соединение, либо путём сохранения чисел на вторичном носителе, таком как файл на диске или магнитная лента.

Разногласия в порядке хранения приводят к путанице с числами. Если хост с малым порядком байтов (Intel, VAX) хранит 0x12345678 (305419896 в десятичной системе), то хост с большим порядком байтов (Motorola, Sparc, PA) считывает его как 0x78563412 (2018915346 в десятичной системе). Alpha и MIPS могут быть как теми, так и другими: Digital/Compaq использовали/используют их в режиме малого порядка байтов; SGI/Cray используют их в режиме большого порядка байтов. Чтобы избежать этой проблемы в сетевых (сокетовых) соединениях, используйте форматы pack и unpack n и N, «сетевые» порядки. Они гарантируют переносимость.

Начиная с Perl 5.10.0, вы также можете использовать модификаторы > и < для принудительного задания порядка байтов — большого или малого. Это полезно, если вы хотите сохранить целые числа со знаком или 64-битные целые числа, например.

Вы можете изучить порядок байтов вашей платформы, распаковывая структуру данных, упакованную в родном формате, например:

print unpack("h*", pack("s2", 1, 2)), "\n";
# '10002000' on e.g. Intel x86 or Alpha 21064 in little-endian mode
# '00100020' on e.g. Motorola 68040

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

$is_big_endian   = unpack("h*", pack("s", 1)) =~ /01/;
$is_little_endian = unpack("h*", pack("s", 1)) =~ /^1/;

Разная ширина может привести к усечению даже между платформами с одинаковым порядком байтов. Платформа с меньшей шириной теряет старшие части числа. Нет хорошего решения этой проблемы, кроме как избегать передачи или хранения чисел в сыром двоичном формате.

Вы можете обойти обе эти проблемы двумя способами. Либо передавать и хранить числа всегда в текстовом формате вместо двоичного, либо использовать модули, такие как Data::Dumper и Storable (включённые начиная с Perl 5.8). Хранение всех данных в виде текста значительно упрощает задачу.

Файлы и файловые системы

В большинстве платформ файлы структурированы иерархически. Поэтому можно достаточно безопасно предположить, что все платформы поддерживают понятие «пути», чтобы однозначно идентифицировать файл в системе. Однако способ записи этого пути существенно отличается.

Хотя они похожи, спецификации путей файлов различаются между Unix, Windows, Mac OS, OS/2, VMS, VOS, RISC OS и, вероятно, другими. Unix, например, является одной из немногих ОС, которые имеют элегантную идею единственного корневого каталога.

DOS, OS/2, VMS, VOS и Windows могут работать аналогично Unix с / в качестве разделителя путей или своими собственными специфическими способами (например, с несколькими корневыми каталогами и различными «бескорневыми» файлами устройств, такими как NIL: и LPT:).

Mac OS 9 и более ранние версии использовали : в качестве разделителя путей вместо /.

Файловая система может не поддерживать жёсткие ссылки (link) или символические ссылки (symlink, readlink, lstat).

Файловая система может не поддерживать метки времени доступа или изменения (что означает, что единственной переносимой меткой времени является метка изменения), или разрешение в одну секунду для любых меток времени (например, файловая система FAT ограничивает разрешение по времени двумя секундами).

«Метка времени изменения узла» (файл-тест -C) может фактически быть «меткой времени создания» (чем она не является в Unix).

VOS perl может эмулировать имена файлов Unix с / в качестве разделителя путей. Символы больше, меньше, решётка и знак процента в именах путей всегда принимаются.

RISC OS perl может эмулировать имена файлов Unix с / в качестве разделителя путей или использовать родной формат с . в качестве разделителя путей и : для обозначения файловых систем и дисков.

Не предполагайте семантику доступа к файловой системе Unix: что чтение, запись и выполнение — это все разрешения, и даже если они существуют, что их семантика (например, что означают r, w, и x в каталоге) такие же, как в Unix. Различные совместимые слои Unix/POSIX обычно пытаются заставить интерфейсы, такие как chmod, работать, но иногда просто нет хорошего соответствия.

Модули File::Spec предоставляют методы для обработки спецификаций путей и возвращают результаты в родном формате для каждой платформы. Это часто не требуется, так как пути в стиле Unix понимаются Perl на каждой поддерживаемой платформе, но если вам нужно создать родные пути для родного инструмента, который не понимает синтаксис Unix, или если вы работаете с путями или компонентами путей в неизвестном (а значит, возможно, родном) синтаксисе, File::Spec — ваш помощник. Вот два кратких примера:

use File::Spec::Functions;
chdir(updir());        # go up one directory

# Concatenate a path from its components
my $file = catfile(updir(), 'temp', 'file.txt');
# on Unix:    '../temp/file.txt'
# on Win32:   '..\temp\file.txt'
# on VMS:     '[-.temp]file.txt'

В общем случае в производственном коде пути к файлам не должны быть жёстко закодированы. Лучше делать их пользовательскими или считывать из файла конфигурации, помня о том, что синтаксис пути к файлам различается на разных машинах.

Это особенно заметно в скриптах, таких как Makefiles и наборы тестов, которые часто предполагают / в качестве разделителя подкаталогов.

Также полезен модуль File::Basename из стандартного дистрибутива, который разбивает имя пути на части (имя базового файла, полный путь к каталогу и расширение файла).

Даже на одной платформе (если можно назвать Unix одной платформой), помните, что нельзя рассчитывать на существование или содержимое конкретных файлов или каталогов, специфичных для системы, таких как /etc/passwd, /etc/sendmail.conf, /etc/resolv.conf или даже /tmp/. Например, /etc/passwd может существовать, но не содержать зашифрованные пароли, потому что система использует форму усиленной защиты. Или она может не содержать всех учетных записей, потому что система использует NIS. Если код действительно нуждается в таком файле, включите в документацию описание файла и его формата в код, а затем сделайте лёгким для пользователя переопределение расположения файла по умолчанию.

Не предполагайте, что текстовый файл закончится символом новой строки. Они должны, но люди забывают.

Не допускайте наличия двух файлов или каталогов с одинаковым именем, но разным регистром, например, test.pl и Test.pl, так как во многих платформах имена файлов регистронезависимы (или, по крайней мере, регистроустойчивы). Также старайтесь избегать символов, не являющихся словами (кроме .), в именах и придерживаться соглашения 8.3 для максимальной переносимости, даже если это кажется обременительным.

Аналогично, при использовании модуля AutoSplit старайтесь придерживаться соглашений 8.3 по именованию и регистронезависимости или, по крайней мере, сделайте так, чтобы полученные файлы имели уникальное (регистронезависимое) первое 8 символов.

Пробелы в именах файлов допускаются в большинстве систем, но не во всех, и даже в тех системах, где они допускаются, некоторые утилиты могут сбиться с толку такими пробелами.

Во многих системах (DOS, VMS ODS-2) не может быть более одного . в именах файлов.

Не предполагайте, что > не будет первым символом имени файла. Всегда используйте трёхаргументную версию open:

open my $fh, '<', $existing_file) or die $!;

Двухаргументная open является магической и может переводить символы, такие как >, <, и | в именах файлов, что обычно является неправильным действием. sysopen и трёхаргументная open не имеют этой проблемы.

Не используйте : в качестве части имени файла, поскольку во многих системах он используется для собственных семантик (Mac OS Classic для разделения компонентов пути, многие сетевые схемы и утилиты для разделения имени узла и пути и так далее). По тем же причинам избегайте @, ; и |.

Не предполагайте, что в именах путей можно заменить два ведущих слэша // на один: некоторые сетевые и кластерные файловые системы имеют специальные семантики для этого. Позвольте операционной системе разобраться с этим.

Переносимые символы имени файла, как определено ANSI C, это

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
. _ -

и - не должны быть первым символом. Если вы хотите быть предельно точными, оставайтесь регистронезависимыми и в рамках соглашения 8.3 об именовании (все файлы и каталоги должны быть уникальными в одном каталоге, если их имена в нижнем регистре и усечены до восьми символов перед ., если таковые имеются, и до трёх символов после ., если таковые имеются). (И не используйте . в именах каталогов.)

Взаимодействие с системой

Не все платформы предоставляют командную строку. Как правило, это платформы, которые в основном полагаются на графический интерфейс пользователя (GUI) для взаимодействия с пользователем. Программа, требующая интерфейса командной строки, может не работать везде. Скорее всего, с этим должен разобраться пользователь программы, поэтому не стоит беспокоиться об этом.

Некоторые платформы не могут удалить или переименовать файлы, удерживаемые системой открытыми; это ограничение также может распространяться на изменение метаданных файловой системы, таких как разрешения файлов или владельцы. Помните о необходимости close файлов, когда вы с ними закончили. Не unlink или rename открытого файла. Не tie или open уже привязанного или открытого файла; untie или close его сначала.

Не открывайте один и тот же файл более одного раза для записи, так как некоторые операционные системы устанавливают обязательные блокировки на таких файлах.

Не предполагайте, что права записи/модификации в каталоге дают право добавлять или удалять файлы/каталоги в этом каталоге. Это зависит от файловой системы: в некоторых файловых системах вам также нужны права записи/модификации (или даже только) в самом файле/каталоге. В некоторых файловых системах (AFS, DFS) разрешение на добавление/удаление записей в каталоге — это совершенно отдельное разрешение.

Не предполагайте, что однократное использование unlink полностью удаляет файл: в некоторых файловых системах (прежде всего в VMS) есть файловые системы с версиями, и unlink удаляет только последнюю версию (он не удаляет все версии, потому что по умолчанию встроенные инструменты на этих платформах удаляют только последнюю версию).

1 while unlink "file";

Это завершит выполнение, если файл по какой-то причине не может быть удалён (защищён, отсутствует и так далее).

Не полагайтесь на существование конкретной переменной окружения в %ENV. Не полагайтесь на то, что записи в %ENV являются чувствительными к регистру или даже сохраняют регистр. Не пытайтесь очистить %ENV, сказав %ENV = ();, или, если вам действительно нужно, сделайте это условным на основе $^O ne 'VMS', так как в VMS таблица %ENV представляет собой нечто большее, чем просто таблицу пар ключ-значение строк на процесс.

В VMS некоторые записи в хеше %ENV динамически создаются при чтении, если они ранее не существовали. Значения для $ENV{HOME}, $ENV{TERM}, $ENV{PATH}, и $ENV{USER}, известны как динамически генерируемые. Конкретные имена, которые динамически генерируются, могут варьироваться в зависимости от версии библиотеки C на VMS, и их может быть больше, чем документировано.

В VMS по умолчанию изменения в хеше %ENV сохраняются после завершения работы Perl. Последующие вызовы Perl в том же процессе могут непреднамеренно унаследовать настройки окружения, которые были предназначены для временного использования.

Не полагайтесь на сигналы или %SIG для чего-либо.

Не полагайтесь на подстановку имён файлов. Используйте opendir, readdir и closedir вместо этого.

Не полагайтесь на переменные окружения или текущие каталоги, специфичные для программы.

Не полагайтесь на конкретные значения $!, ни числовые, ни, особенно, строковые. Пользователи могут изменять свой локали, что приводит к тому, что сообщения об ошибках будут переведены на их языки. Если вы можете доверять POSIX-совместимой среде, вы можете портативно использовать символы, определённые модулем Errno, такие как ENOENT. И не доверяйте значениям $! вообще, кроме как сразу после неудачного системного вызова.

Имена команд против путей к файлам

Не предполагайте, что имя, используемое для вызова команды или программы с помощью system или exec, также может быть использовано для проверки существования файла, содержащего исполняемый код этой команды или программы. Во-первых, многие системы имеют «внутренние» команды, которые являются встроенными в оболочку или операционную систему, и, хотя эти команды можно вызвать, соответствующего файла нет. Во-вторых, в некоторых операционных системах (например, Cygwin, DJGPP, OS/2 и VOS) для исполняемых файлов требуются суффиксы; эти суффиксы разрешены для имени команды, но не являются обязательными. Таким образом, команда, подобная perl, может существовать в файле с именем perl, perl.exe или perl.pm, в зависимости от операционной системы. Переменная $Config{_exe} в модуле Config содержит суффикс исполняемого файла, если таковой имеется. В-третьих, порт VMS тщательно настраивает $^X и $Config{perlpath} таким образом, что дальнейшая обработка не требуется. Это тоже хорошо, потому что сопоставление с образцом, используемое ниже, в противном случае должно было бы обрабатывать возможный конечный номер версии в имени файла VMS.

Для преобразования $^X в имя файла с учётом требований различных возможностей операционной системы, скажите:

use Config;
my $thisperl = $^X;
if ($^O ne 'VMS') {
    $thisperl .= $Config{_exe}
        unless $thisperl =~ m/\Q$Config{_exe}\E$/i;
}

Для преобразования $Config{perlpath} в имя файла, скажите:

use Config;
my $thisperl = $Config{perlpath};
if ($^O ne 'VMS') {
    $thisperl .= $Config{_exe}
        unless $thisperl =~ m/\Q$Config{_exe}\E$/i;
}

Сеть

Не предполагайте, что вы можете получить доступ к общедоступному интернету.

Не предполагайте, что существует только один способ прохождения брандмауэров к общедоступному интернету.

Не предполагайте, что вы можете получить доступ к внешнему миру через любой другой порт, кроме 80, или какой-либо веб-прокси. ftp заблокирован во многих брандмауэрах.

Не предполагайте, что вы можете отправлять электронную почту, подключившись к локальному SMTP-порту.

Не предполагайте, что вы можете получить доступ к себе или любому узлу по имени «localhost». То же самое относится и к «127.0.0.1». Вам нужно будет попробовать оба.

Не предполагайте, что у узла есть только одна сетевая карта или что он не может привязаться к нескольким виртуальным IP-адресам.

Не предполагайте конкретное имя сетевого устройства.

Не предполагайте, что определённый набор ioctl будет работать.

Не предполагайте, что вы можете отправить ping узлам и получить ответы.

Не предполагайте, что какой-либо конкретный порт (сервис) будет отвечать.

Не предполагайте, что Sys::Hostname (или любой другой API или команда) возвращает либо полное доменное имя, либо имя домена без квалификатора: всё зависит от того, как была настроена система. Также помните, что для таких вещей, как DHCP и NAT, возвращаемое вами имя хоста может быть не очень полезным.

Все вышеперечисленные «не» могут показаться устрашающими, и это так, но ключ заключается в плавном ухудшении, если невозможно получить доступ к конкретному сетевому сервису, которого вы хотите. Остановки или зависания не выглядят профессионально.

Взаимодействие между процессами (IPC)

В целом, не осуществляйте прямой доступ к системе в коде, предназначенном для переноса. Это означает, что нет system, exec, fork, pipe, `` или qx//, open с |, а также никаких других вещей, которые делают Perl-хакера стоящим своего названия.

Команды, запускающие внешние процессы, как правило, поддерживаются на большинстве платформ (хотя многие из них не поддерживают форкинг). Проблема с их использованием возникает из того, на что вы их вызываете. Внешние инструменты часто имеют разные имена на разных платформах, могут быть недоступны в том же месте, принимать разные аргументы, вести себя по-разному и часто представлять свои результаты в платформозависимой форме. Следовательно, вы вряд ли должны полагаться на них для получения согласованных результатов. (Впрочем, если вы вызываете netstat -a, вы, вероятно, не ожидаете, что это будет работать как на Unix, так и на CP/M.)

Один из особенно распространённых фрагментов Perl-кода заключается в открытии канала к sendmail:

open(my $mail, '|-', '/usr/lib/sendmail -t')
    or die "cannot fork sendmail: $!";

Это хорошо для системного программирования, когда sendmail известен как доступный. Но это не хорошо для многих систем, не являющихся Unix, и даже для некоторых систем Unix, на которых sendmail может быть не установлен. Если требуется портативное решение, см. различные пакеты в CPAN, которые с этим справляются. Mail::Mailer и Mail::Send в пакете MailTools обычно используются и предоставляют несколько методов отправки почты, включая mail, sendmail, и прямой SMTP (через Net::SMTP), если почтовый агент пересылки недоступен. Mail::Sendmail — отдельный модуль, предоставляющий простую платформонезависимую отправку почты.

IPC системы V Unix (msg*(), sem*(), shm*()) недоступна даже на всех платформах Unix.

Не используйте ни результат pack("N", 10, 20, 30, 40), ни строки v (такие как v10.20.30.40) для представления IPv4-адресов: оба формата просто упаковывают четыре байта в сетевой порядок. Не гарантируется, что это будет равно структуре C in_addr (которую внутренне использует код сокетов). Для обеспечения переноса используйте процедуры модуля Socket, такие как inet_aton, inet_ntoa и sockaddr_in.

Правило для портабельного кода заключается в следующем: делайте всё в портабельном Perl или используйте модуль (который может реализовать это с помощью платформоспецифичного кода, но предоставляет общий интерфейс).

Внешние подпрограммы (XS)

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

Различного рода проблема с портативностью возникает при написании кода XS: доступность компилятора C на системе конечного пользователя. C сам по себе несёт проблемы с портативностью, и написание кода XS выявит некоторые из них. Написание чисто Perl-кода — более простой способ обеспечения портативности.

Стандартные модули

В целом, стандартные модули работают на разных платформах. Заметные исключения — модуль CPAN (который в настоящее время создаёт соединения с внешними программами, которые могут быть недоступны), платформоспецифические модули (например, ExtUtils::MM_VMS) и модули DBM.

Нет одного модуля DBM, доступного на всех платформах. SDBM_File и другие обычно доступны на всех Unix и DOS-подобных портах, но не в MacPerl, где доступны только NDBM_File и DB_File.

Хорошая новость заключается в том, что по крайней мере какой-то модуль DBM должен быть доступен, и AnyDBM_File будет использовать тот модуль, который найдёт. Конечно, тогда код должен быть достаточно строгим, снижаясь до наименьшего общего знаменателя (например, не превышая 1 КБ для каждой записи), чтобы он работал с любым модулем DBM. См. AnyDBM_File для получения дополнительной информации.

Время и дата

Система отображения времени суток и даты календаря управляется различными способами. Не предполагайте, что часовой пояс хранится в $ENV{TZ}, и даже если это так, не предполагайте, что вы можете управлять часовым поясом через эту переменную. Не делайте предположений о трехбуквенных аббревиатурах часовых поясов (например, что MST будет обозначать горное стандартное время, поскольку известно, что это может обозначать московское стандартное время). Если вам необходимо использовать часовые пояса, выразите их в недвусмысленном формате, например, точное количество минут смещения от UTC или формате часового пояса POSIX.

Не предполагайте, что эпоха начинается в 00:00:00 1 января 1970 года, поскольку это зависит от операционной системы и реализации. Лучше хранить дату в однозначном представлении. Стандарт ISO 8601 определяет формат даты как ГГГГ-ММ-ДД или ГГГГ-ММ-ДДТЧЧ:ММ:СС (буква «Т» отделяет дату от времени). Используйте ISO 8601 вместо того, чтобы заставлять нас догадываться, что означает дата 02/03/04. ISO 8601 даже сортируется в порядке возрастания. Текстовое представление (например, «1987-12-18») может быть легко преобразовано в значение, специфичное для операционной системы, с помощью модуля, такого как Time::Piece (см. "Разбор дат" в Time::Piece) или Date::Parse. Массив значений, таких как те, что возвращаются localtime, можно преобразовать в представление, специфичное для операционной системы, с помощью Time::Local.

При расчете конкретного времени, например, для тестов в модулях времени или дат, может быть уместно рассчитать смещение для эпохи.

use Time::Local qw(timegm);
my $offset = timegm(0, 0, 0, 1, 0, 70);

Значение $offset в Unix будет 0, а в Mac OS Classic — некоторым большим числом. $offset затем можно добавить к значению времени Unix, чтобы получить правильное значение на любой системе.

Наборы символов и кодировка символов

Предполагайте минимально о наборах символов.

Не делайте предположений о числовых значениях (ord, chr) символов. Не используйте явные диапазоны кодовых точек (например, \xHH-\xHH). Однако начиная с Perl v5.22, диапазоны символьных классов в квадратных скобках, указанные как qr/[\N{U+HH}-\N{U+HH}]/, являются переносимыми, а начиная с Perl v5.24, те же диапазоны являются переносимыми в tr///. Вы можете переносимо использовать символьные классы, такие как [:print:].

Не предполагайте, что алфавитные символы закодированы непрерывно (в числовом смысле). Могут быть пробелы. Специальная кодировка в Perl, однако, гарантирует, что все подмножества qr/[A-Z]/, qr/[a-z]/, и qr/[0-9]/ ведут себя ожидаемо. tr/// ведет себя одинаково для этих диапазонов. В шаблонах любые диапазоны, указанные с конечными точками с использованием \N{...} обозначений, гарантируют переносимость наборов символов, но это ошибка в Perl v5.22, что это неверно для tr///, исправленная в v5.24.

Не делайте предположений о порядке символов. Строчные буквы могут идти до или после заглавных букв; строчные и заглавные могут быть чередующимися, так что и «a», и «A» предшествуют «b»; акцентированные и другие международные символы могут быть чередующимися, так что «ä» предшествует «b». Для сортировки всего этого можно использовать Unicode::Collate.

Международные особенности

Если вы можете предположить POSIX (довольно большое предположение), вы можете узнать больше о системе локалей POSIX из perllocale. Система локалей по крайней мере пытается сделать вещи немного более переносимыми, или по крайней мере более удобными и дружественными для пользователей, не использующих английский язык. Система влияет на наборы символов и кодировку, а также на форматирование дат и времени — среди прочего.

Если вам действительно нужно работать с международными данными, вы должны рассмотреть Unicode. См. perluniintro и perlunicode для получения дополнительной информации.

По умолчанию Perl предполагает, что ваш исходный код написан в наборе символов ASCII 8-битный суперсет. Для вставки символов Unicode в ваши строки и регулярные выражения можно использовать \x{HH} или (более переносимо) \N{U+HH} обозначения. Также можно использовать прагму utf8 и написать свой код в UTF-8, что позволяет использовать символы Unicode напрямую (не только в строковых конструкциях, но и в идентификаторах).

Системные ресурсы

Если ваш код предназначен для систем с сильно ограниченной (или отсутствующей!) виртуальной памятью, то следует быть особенно внимательным, избегая таких неэффективных конструкций, как:

my @lines = <$very_large_file>;            # bad

while (<$fh>) {$file .= $_}                # sometimes bad
my $file = join('', <$fh>);                # better

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

Безопасность

Большинство многопользовательских платформ предоставляют базовые уровни безопасности, обычно реализованные на уровне файловой системы. Однако некоторые из них, к сожалению, этого не делают. Таким образом, понятие идентификатора пользователя или «домашнего» каталога, или даже состояния входа в систему может быть не распознано на многих платформах. Если вы пишете программы, которые учитывают безопасность, обычно лучше знать, на какой тип системы вы будете работать, чтобы вы могли написать код, явно предназначенный для этой платформы (или класса платформ).

Не предполагайте семантики доступа к файловой системе Unix: операционная система или файловая система могут использовать системы ACL, которые являются более богатыми языками, чем обычные rwx. Даже если rwx существуют, их семантика может быть другой.

(С точки зрения безопасности, проверка разрешений перед выполнением операции бессмысленна: если это делать, могут возникнуть гонки. Кто-то или что-то может изменить разрешения между проверкой разрешений и фактической операцией. Просто попробуйте выполнить операцию.)

Не предполагайте семантики пользователей и групп Unix: в частности, не ожидайте, что $< и $> (или $( и $)) будут работать для переключения идентичностей (или принадлежностей).

Не предполагайте семантики set-uid и set-gid. (И даже если вы это сделаете, подумайте дважды: set-uid и set-gid — это известный источник проблем с безопасностью.)

Стиль

В тех случаях, когда необходимо иметь код, специфичный для платформы, рассмотрите возможность размещения платформозависимого кода в одном месте, что облегчит портирование на другие платформы. Используйте модуль Config и специальную переменную $^O для различения платформ, как описано в "PLATFORMS".

Будьте внимательны к "синдрому else":

if ($^O eq 'MSWin32') {
  # code that assumes Windows
} else {
  # code that assumes Linux
}

Ветка else должна использоваться для действительно окончательного варианта, а не для кода, специфичного для какой-либо платформы.

Обращайте внимание на тесты, которые вы предоставляете со своим модулем или программами. Код модуля может быть полностью переносимым, но его тесты могут быть нет. Это часто случается, когда тесты запускают другие процессы или вызывают внешние программы для помощи в тестировании, или когда (как отмечалось выше) тесты предполагают определённые вещи о файловой системе и путях. Старайтесь не полагаться на специфичный для платформы стиль вывода ошибок, например, при проверке $! после неудачного системного вызова. Использование $! для чего-либо кроме вывода на экран сомнительно (хотя см. модуль Errno для разумной переносимой проверки кода ошибки). Некоторые платформы ожидают определенный формат вывода, и Perl на этих платформах может быть соответственно настроен. В частности, не привязывайте регулярное выражение при проверке значения ошибки.

Тестеры CPAN

Модули, загруженные в CPAN, тестируются различными добровольцами на разных платформах. Эти тестеры CPAN уведомляются по электронной почте о каждом новом загружении и отвечают на список с PASS, FAIL, NA (не применимо к этой платформе) или UNKNOWN (неизвестно), вместе с любыми соответствующими примечаниями.

Цель тестирования двояка: во-первых, помочь разработчикам исправить любые проблемы в их коде, которые возникают из-за отсутствия тестирования на других платформах; во-вторых, предоставить пользователям информацию о том, работает ли данный модуль на данной платформе.

Также см.:

  • Список рассылки: cpan-testers-discuss@perl.org

  • Результаты тестирования: http://www.cpantesters.org/

ПЛАТФОРМЫ

Perl создаётся с переменной $^O, которая указывает на операционную систему, на которой он был создан. Это было реализовано для ускорения кода, который в противном случае должен был бы use Config и использовать значение $Config{osname}. Конечно, для получения более подробной информации о системе рекомендуется посмотреть в %Config.

%Config нельзя всегда доверять, поскольку она была создана во время компиляции. Если perl был создан в одном месте, а затем перенесён в другое, некоторые значения могут быть неверными. Значения могут быть даже отредактированы после факта.

Unix

Perl работает на поразительно разнообразных платформах Unix и Unix-подобных системах (см., например, большинство файлов в каталоге hints/ в наборе исходных кодов). На большинстве этих систем значение $^O (следовательно, и $Config{osname}) определяется либо преобразованием первой части строки, полученной в результате ввода uname -a (или аналогичной команды) в командной строке в нижний регистр и удалением знаков препинания, либо путём проверки файловой системы на наличие уникальных файлов, таких как ядро или заголовочный файл. Вот, например, несколько популярных вариантов Unix:

uname         $^O        $Config{archname}
--------------------------------------------
AIX           aix        aix
BSD/OS        bsdos      i386-bsdos
Darwin        darwin     darwin
DYNIX/ptx     dynixptx   i386-dynixptx
FreeBSD       freebsd    freebsd-i386
Haiku         haiku      BePC-haiku
Linux         linux      arm-linux
Linux         linux      armv5tel-linux
Linux         linux      i386-linux
Linux         linux      i586-linux
Linux         linux      ppc-linux
HP-UX         hpux       PA-RISC1.1
IRIX          irix       irix
Mac OS X      darwin     darwin
NeXT 3        next       next-fat
NeXT 4        next       OPENSTEP-Mach
openbsd       openbsd    i386-openbsd
OSF1          dec_osf    alpha-dec_osf
reliantunix-n svr4       RM400-svr4
SCO_SV        sco_sv     i386-sco_sv
SINIX-N       svr4       RM400-svr4
sn4609        unicos     CRAY_C90-unicos
sn6521        unicosmk   t3e-unicosmk
sn9617        unicos     CRAY_J90-unicos
SunOS         solaris    sun4-solaris
SunOS         solaris    i86pc-solaris
SunOS4        sunos      sun4-sunos

Поскольку значение $Config{archname} может зависеть от архитектуры оборудования, оно может изменяться больше, чем значение $^O.

DOS и производные

Perl давно портирован на микрокомпьютеры на базе Intel, работающие под системами, такими как PC-DOS, MS-DOS, OS/2, и большинство платформ Windows, которые вы можете упомянуть (за исключением Windows CE, если вы считаете её таковой). Пользователи, знакомые с оболочками типа COMMAND.COM или CMD.EXE, должны знать, что каждое из этих спецификаций файлов может иметь тонкие различия:

my $filespec0 = "c:/foo/bar/file.txt";
my $filespec1 = "c:\\foo\\bar\\file.txt";
my $filespec2 = 'c:\foo\bar\file.txt';
my $filespec3 = 'c:\\foo\\bar\\file.txt';

Вызовы системного интерфейса принимают / или \ в качестве разделителя путей. Однако многие утилиты командной строки, наследующие от DOS, интерпретируют / как префикс опций, что может привести к проблемам с именами файлов, содержащими /. Помимо вызова внешних программ, / будет работать без проблем и, вероятно, лучше, так как это более согласуется с распространенным использованием и избегает необходимости запоминать, что нужно и что не нужно экранировать.

Файловая система DOS FAT может вместить только имена файлов в формате "8.3". В системах файлов HPFS (OS/2) и NTFS (NT), поддерживающих "регистронезависимое, но регистросохраняющее" сравнение, следует быть внимательными при работе с результатами функций, таких как readdir, или при использовании функций, таких как open или opendir.

DOS также рассматривает некоторые имена файлов как специальные, такие как AUX, PRN, NUL, CON, COM1, LPT1, LPT2 и т. д. К сожалению, иногда эти имена файлов не будут работать, даже если вы укажете явный префикс каталога. Лучше избегать таких имён файлов, если вы хотите, чтобы ваш код был переносимым для DOS и его производных. К сожалению, сложно знать, что они все представляют собой.

Пользователи этих операционных систем также могут использовать скрипты, такие как pl2bat.bat, для создания оболочек вокруг своих скриптов.

Перевод новой строки (\n) выполняется как \015\012 системой ввода-вывода при чтении и записи файлов (см. "Новые строки"). binmode($filehandle) сохранит \n в переводе как \012 для этого файлового дескриптора. binmode всегда следует использовать для кода, работающего с бинарными данными. Предполагается, что вы заранее понимаете, что ваши данные являются бинарными. Программы общего назначения часто не должны делать предположений о своих данных.

Переменная $^O и значения $Config{archname} для различных DOS-подобных Perl'ов представлены ниже:

OS             $^O       $Config{archname}  ID    Version
---------------------------------------------------------
MS-DOS         dos       ?
PC-DOS         dos       ?
OS/2           os2       ?
Windows 3.1    ?         ?                  0     3 01
Windows 95     MSWin32   MSWin32-x86        1     4 00
Windows 98     MSWin32   MSWin32-x86        1     4 10
Windows ME     MSWin32   MSWin32-x86        1     ?
Windows NT     MSWin32   MSWin32-x86        2     4 xx
Windows NT     MSWin32   MSWin32-ALPHA      2     4 xx
Windows NT     MSWin32   MSWin32-ppc        2     4 xx
Windows 2000   MSWin32   MSWin32-x86        2     5 00
Windows XP     MSWin32   MSWin32-x86        2     5 01
Windows 2003   MSWin32   MSWin32-x86        2     5 02
Windows Vista  MSWin32   MSWin32-x86        2     6 00
Windows 7      MSWin32   MSWin32-x86        2     6 01
Windows 7      MSWin32   MSWin32-x64        2     6 01
Windows 2008   MSWin32   MSWin32-x86        2     6 01
Windows 2008   MSWin32   MSWin32-x64        2     6 01
Windows CE     MSWin32   ?                  3
Cygwin         cygwin    cygwin

Различные версии Perl для MSWin32 могут различать операционную систему, на которой они работают, по значению пятого элемента списка, возвращаемого функцией Win32::GetOSVersion(). Например:

if ($^O eq 'MSWin32') {
    my @os_version_info = Win32::GetOSVersion();
    print +('3.1','95','NT')[$os_version_info[4]],"\n";
}

Также существуют Win32::IsWinNT()|Win32/Win32::IsWinNT(), Win32::IsWin95()|Win32/Win32::IsWin95(), и Win32::GetOSName(); попробуйте perldoc Win32. Весьма переносимая функция POSIX::uname() тоже будет работать:

c:\> perl -MPOSIX -we "print join '|', uname"
Windows NT|moonru|5.0|Build 2195 (Service Pack 2)|x86

Ошибки, устанавливаемые функциями Winsock, теперь напрямую помещаются в $^E, а соответствующие коды ошибок WSAE* теперь экспортируются из модулей Errno и POSIX для проверки.

Предыдущее поведение, заключающееся в помещении ошибок (преобразованных в коды ошибок POSIX-стиля E* начиная с Perl 5.20.0) в $!, было ошибочным из-за неэквивалентности одноимённых констант ошибок Winsock и POSIX, взаимосвязь которых, к сожалению, была установлена так или иначе начиная с Perl 5.8.0.

Новое поведение обеспечивает гораздо более надежное решение для проверки ошибок Winsock в переносимом программном обеспечении, без случайного сопоставления тестов POSIX, предназначенных для других ОС и имеющих иное значение для Winsock.

Старое поведение в настоящее время сохраняется, со всеми его недостатками, для обеспечения обратной совместимости, но пользователям рекомендуется изменить любой код, проверяющий $! на E* константы ошибок Winsock, на проверку $^E на WSAE* константы. После подходящего периода устаревания, начавшегося с Perl 5.24, старое поведение может быть удалено, оставляя $! без изменений после вызовов функций Winsock, чтобы избежать возможной путаницы, касающейся переменной ошибки, которую следует проверять.

См. также:

  • Окружение djgpp для DOS, http://www.delorie.com/djgpp/ и perldos.

  • Окружение EMX для DOS, OS/2 и т. д. emx@iaehv.nl, ftp://hobbes.nmsu.edu/pub/os2/dev/emx/ Также perlos2.

  • Инструкции по сборке для Win32 в perlwin32 или в среде Cygnus в perlcygwin.

  • Модули Win32::* в Win32.

  • Страницы ActiveState, http://www.activestate.com/

  • Окружение Cygwin для Win32; README.cygwin (установлено как perlcygwin), http://www.cygwin.com/

  • Окружение U/WIN для Win32, http://www.research.att.com/sw/tools/uwin/

  • Инструкции по сборке для OS/2, perlos2

VMS

Perl на VMS описан в perlvms в дистрибутиве Perl.

Официальное название VMS на данный момент — OpenVMS.

Взаимодействие с Perl из оболочки команд Digital Command Language (DCL) часто требует использования других кавычек, чем в оболочках Unix. Например:

$ perl -e "print ""Hello, world.\n"""
Hello, world.

Существуют различные способы обернуть ваши скрипты Perl в файлы DCL .COM, если вам это нужно. Например:

$ write sys$output "Hello from DCL!"
$ if p1 .eqs. ""
$ then perl -x 'f$environment("PROCEDURE")
$ else perl -x - 'p1 'p2 'p3 'p4 'p5 'p6 'p7 'p8
$ deck/dollars="__END__"
#!/usr/bin/perl

print "Hello from Perl!\n";

__END__
$ endif

Будьте осторожны с $ ASSIGN/nolog/user SYS$COMMAND: SYS$INPUT , если ваш скрипт Perl в DCL ожидает выполнения действий, таких как $read = <STDIN>;.

Операционная система VMS имеет две файловые системы, определяемые уровнем организации данных на диске (ODS): ODS-2 и его преемник ODS-5. Первоначальный порт Perl на VMS предшествует ODS-5, но все текущие тесты и разработки предполагают ODS-5 и его возможности, включая сохранение регистра, расширенные символы в спецификациях файлов и имена длиной до 8192 байт.

Perl на VMS может принимать как спецификации файлов в формате VMS, так и в формате Unix, как в одном из следующих примеров:

$ perl -ne "print if /perl_setup/i" SYS$LOGIN:LOGIN.COM
$ perl -ne "print if /perl_setup/i" /sys$login/login.com

но не смешанный формат, как в:

$ perl -ne "print if /perl_setup/i" sys$login:/login.com
Can't open sys$login:/login.com: file specification syntax error

В общем случае, самый простой путь к переносимости — всегда указывать имена файлов в формате Unix, если они не будут обрабатываться с помощью системных команд или утилит. В связи с этим модуль File::Spec по умолчанию возвращает спецификации в формате, нативном для системы, независимо от входного формата. Этот параметр по умолчанию можно изменить, чтобы всегда возвращать имена файлов в формате Unix, установив логический параметр DECC$FILENAME_UNIX_REPORT в среде.

Тип или расширение файла всегда присутствует в спецификации файла в формате VMS, даже если его длина равна нулю. Это означает, что по умолчанию readdir вернёт хвостовую точку в файле без расширения, так что там, где вы увидите "a" в Unix, вы увидите "a." на VMS. Однако хвостовую точку можно отключить, включив в среде логический параметр DECC$READDIR_DROPDOTNOTYPE (см. документацию CRTL по логическим именам параметров).

То, что \n представляет собой, зависит от типа открытого файла. Обычно это \012, но также может быть \015, \012, \015\012, \000, \040 или ничего, в зависимости от организации файлов и формата записей. Модуль VMS::Stdio предоставляет доступ к особым требованиям fopen() для файлов с необычными атрибутами в VMS.

Значение $^O в OpenVMS равно "VMS". Чтобы определить архитектуру, на которой вы работаете, обратитесь к $Config{archname}.

В VMS Perl определяет смещение UTC по логическому имени SYS$TIMEZONE_DIFFERENTIAL. Хотя эпоха VMS началась 17-НОЯ-1858 00:00:00.00, вызовы localtime корректируются для подсчёта смещений от 01-ЯНВ-1970 00:00:00.00, как и в Unix.

См. также:

  • README.vms (установлено как README_vms), perlvms

  • Список рассылки vmsperl, vmsperl-subscribe@perl.org

  • vmsperl в сети, http://www.sidhe.org/vmsperl/index.html

  • Веб-сайт VMS Software Inc., http://www.vmssoftware.com

VOS

Perl на VOS (также известен как OpenVOS) описан в README.vos в дистрибутиве Perl (установлено как perlvos). Perl на VOS может принимать как спецификации файлов в формате VOS, так и в формате Unix, как в одном из следующих примеров:

$ perl -ne "print if /perl_setup/i" >system>notices
$ perl -ne "print if /perl_setup/i" /system/notices

или даже смешанный формат, как в:

$ perl -ne "print if /perl_setup/i" >system/notices

Хотя символ косой черты может встречаться в именах объектов VOS, поскольку порт Perl для VOS интерпретирует его как разделитель пути, файлы, каталоги или ссылки VOS с именами, содержащими символ косой черты, не могут быть обработаны. Такие файлы необходимо переименовать перед обработкой Perl.

В более старых версиях VOS (до OpenVOS Release 17.0) имена файлов ограничены 32 или менее символами, запрещено начинать имена файлов с - символа, и запрещено содержать (пробел) или любой символ из набора !#%&'()*;<=>?.

В более новых версиях VOS (OpenVOS Release 17.0 или более поздние) поддерживаются расширенные имена. В этих версиях имена файлов могут содержать до 255 символов, запрещено начинать имена файлов с - символа, и набор запрещённых символов уменьшен до #%*<>?. Существуют ограничения, касающиеся пробелов и апострофов: эти символы не могут начинать или заканчивать имя, а также не могут непосредственно предшествовать или следовать за точкой. Кроме того, пробел не может непосредственно предшествовать другому пробелу или дефису. Конкретно, запрещены следующие комбинации символов: пробел-пробел, пробел-дефис, точка-пробел, пробел-точка, точка-апостроф, апостроф-точка, ведущий или заключительный пробел и ведущий или заключительный апостроф. Хотя расширенное имя файла ограничено 255 символами, имя пути по-прежнему ограничено 256 символами.

Значение $^O в VOS равно "vos". Чтобы определить архитектуру, на которой вы работаете, обратитесь к $Config{archname}.

См. также:

  • README.vos (установлено как perlvos)

  • Список рассылки VOS.

    Нет специального списка рассылки для Perl на VOS. Вы можете обратиться в центр помощи Stratus Technologies для вашего региона или использовать контактную информацию в файлах дистрибутива на анонимном FTP-сервере Stratus.

  • Stratus Technologies в сети http://www.stratus.com

  • Open-Source ПО VOS в сети http://ftp.stratus.com/pub/vos/vos.html

EBCDIC-платформы

v5.22 ядро Perl работает на z/OS (ранее OS/390). Теоретически оно может работать и на преемниках OS/400 на компьютерах AS/400, а также на VM/ESA и BS2000 для S/390 мэйнфреймов. Такие компьютеры используют внутренне кодировку EBCDIC (обычно кодовую страницу 0037 для OS/400 и 1047 или POSIX-BC для систем S/390).

Остальная часть этого раздела может потребовать обновления, но нам неизвестно, что в ней должно быть. Пожалуйста, отправляйте комментарии на https://github.com/Perl/perl5/issues.

На мэйнфреймах Perl в настоящее время работает под «Unix-системами сервисов для OS/390» (ранее известными как OpenEdition), VM/ESA OpenEdition или системой BS200 POSIX-BC (BS2000 поддерживается в Perl 5.6 и выше). Подробности см. в perlos390. Обратите внимание, что для OS/400 также существует порт Perl 5.8.1/5.10.0 или более поздней версии на PASE, который основан на ASCII (в отличие от ILE, который основан на EBCDIC), см. perlos400.

Начиная с версии R2.5 USS для OS/390 и версии 2.3 VM/ESA эти подсистемы Unix не поддерживают трюк #! shebang для вызова скриптов. Следовательно, на системах OS/390 и VM/ESA скрипты Perl могут выполняться с заголовком, подобным следующему простому скрипту:

: # use perl
    eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
        if 0;
#!/usr/local/bin/perl     # just a comment really

print "Hello from perl!\n";

OS/390 будет поддерживать трюк #! shebang в выпуске 2.8 и последующих. Вызовы system и обратные кавычки могут использовать синтаксис POSIX оболочки на всех системах S/390.

На AS/400, если PERL5 есть в вашем списке библиотек, вам может потребоваться обернуть ваши скрипты Perl в процедуру CL для вызова их следующим образом:

BEGIN
  CALL PGM(PERL5/PERL) PARM('/QOpenSys/hello.pl')
ENDPGM

Это вызовет скрипт Perl hello.pl в корне файловой системы QOpenSys. На AS/400 вызовы system или обратные кавычки должны использовать синтаксис CL.

На этих платформах имейте в виду, что кодовая страница EBCDIC может повлиять на то, что произойдёт с некоторыми функциями Perl (такими как chr, pack, print, printf, ord, sort, sprintf, unpack), а также манипуляции с битами ASCII-константами с помощью операторов, таких как ^, & и |, не говоря уже о работе с сокетными интерфейсами к ASCII-компьютерам (см. "Новые строки").

К счастью, большинство веб-серверов для мэйнфреймов правильно преобразуют \n в следующем операторе в его ASCII-эквивалент (\r одинаковый как в Unix, так и в z/OS):

print "Content-type: text/html\r\n\r\n";

Значения $^O на некоторых из этих платформ включают:

uname         $^O        $Config{archname}
--------------------------------------------
OS/390        os390      os390
OS400         os400      os400
POSIX-BC      posix-bc   BS2000-posix-bc

Некоторые простые трюки для определения того, работаете ли вы на платформе EBCDIC, могут включать любые из следующих (возможно, все):

if ("\t" eq "\005")  { print "EBCDIC may be spoken here!\n"; }

if (ord('A') == 193) { print "EBCDIC may be spoken here!\n"; }

if (chr(169) eq 'z') { print "EBCDIC may be spoken here!\n"; }

Одна вещь, на которую вы, возможно, не захотите полагаться, это кодировка EBCDIC знаков препинания, поскольку они могут отличаться от кодовой страницы к кодовой странице (и как только ваш модуль или скрипт, как предполагается, будет работать с EBCDIC, люди захотят, чтобы он работал со всеми кодовыми страницами EBCDIC).

Также см.:

  • perlos390, perlos400, perlbs2000, perlebcdic.

  • Список perl-mvs@perl.org предназначен для обсуждения вопросов портирования, а также общих вопросов использования всех Perl EBCDIC. Отправьте сообщение «subscribe perl-mvs» на majordomo@perl.org.

  • Информация об AS/400 Perl на http://as400.rochester.ibm.com/, а также в каталоге ports/ на CPAN.

ОС Acorn RISC OS

Поскольку Acorn используют ASCII с новой строкой (\n) в текстовых файлах, как и Unix, и потому что эмуляция имен файлов Unix включена по умолчанию, большинство простых скриптов, вероятно, будут работать «из коробки». Родная файловая система модульная, и отдельные файловые системы могут быть чувствительными или нечувствительными к регистру, и обычно сохраняют регистр. Некоторые родные файловые системы имеют ограничения на длину имени, в которых имена файлов и каталогов молча обрезаются, чтобы соответствовать длине. Скрипты должны понимать, что стандартная файловая система в настоящее время имеет ограничение на длину имени в 10 символов с максимум 77 элементами в каталоге, но другие файловые системы могут не накладывать таких ограничений.

Родные имена файлов имеют вид

Filesystem#Special_Field::DiskName.$.Directory.Directory.File

где

Special_Field is not usually present, but may contain . and $ .
Filesystem =~ m|[A-Za-z0-9_]|
DsicName   =~ m|[A-Za-z0-9_/]|
$ represents the root directory
. is the path separator
@ is the current directory (per filesystem but machine global)
^ is the parent directory
Directory and File =~ m|[^\0- "\.\$\%\&:\@\\^\|\177]+|

По умолчанию перевод имён файлов примерно tr|/.|./|, меняя точки и косые черты.

Обратите внимание, что "ADFS::HardDisk.$.File" ne 'ADFS::HardDisk.$.File' и что вторая стадия $ интерполяции в регулярных выражениях столкнётся с переменной $., если скрипты не будут осторожны.

Логические пути, заданные переменными системы, содержащими разделенные запятыми списки поиска, также разрешены; следовательно, System:Modules является допустимым именем файла, и файловая система будет добавлять Modules к каждой секции System$Path до тех пор, пока имя не укажет на объект на диске. Запись в новый файл System:Modules будет разрешена только в том случае, если System$Path содержит список с одним элементом. Файловая система также будет расширять переменные системы в именах файлов, если они заключены в угловые скобки, поэтому <System$Dir>.Modules будет искать файл $ENV{'System$Dir'} . 'Modules'. Явным следствием этого является то, что полные имена файлов могут начинаться с <>, и трёх-аргументная форма open всегда должна использоваться.

Так как . использовался в качестве разделителя каталогов, и имена файлов не могли считаться уникальными после 10 символов, Acorn реализовали компилятор C, чтобы убрать заключительный .c .h .s и .o суффикс из имён файлов, указанных в исходном коде, и сохранять соответствующие файлы в подкаталогах, названных по имени суффикса. Следовательно, файлы переводятся:

foo.h           h.foo
C:foo.h         C:h.foo        (logical path variable)
sys/os.h        sys.h.os       (C compiler groks Unix-speak)
10charname.c    c.10charname
10charname.o    o.10charname
11charname_.c   c.11charname   (assuming filesystem truncates at 10)

Перевод имен файлов библиотекой эмуляции Unix предполагает, что такой перевод необходим, и он позволяет пользователю определять список известных суффиксов, которые он будет транспонировать таким образом. Это может показаться прозрачным, но учтите, что с этими правилами foo/bar/baz.h и foo/bar/h/baz оба отображаются как foo.bar.h.baz, и что readdir и glob не могут и не пытаются эмулировать обратное отображение. Другие . в именах файлов переводятся в /.

Как подразумевается выше, среда, к которой обращаются через %ENV, является глобальной, и соглашение заключается в том, что переменные среды, специфичные для программы, имеют вид Program$Name. Каждая файловая система поддерживает текущий каталог, и текущий каталог текущей файловой системы является глобальным текущим каталогом. Следовательно, дружественные программы не изменяют текущий каталог, но полагаются на полные имена файлов, и программы (и файлы Make) не могут предполагать, что они могут создать дочерний процесс, который может изменить текущий каталог без влияния на родительский (и всех остальных).

Так как родные файловые дескрипторы операционной системы являются глобальными и в настоящее время выделены до 255, причём 0 — зарезервированное значение, библиотека эмуляции Unix эмулирует Unix-файловые дескрипторы. Следовательно, вы не можете полагаться на передачу STDIN, STDOUT, или STDERR своим дочерним процессам.

Желание пользователей выражать имена файлов в формате <Foo$Dir>.Bar в командной строке без кавычек также вызывает проблемы: `` захват вывода команды должен угадывать. Он предполагает, что строка <[^<>]+\$[^<>]> — ссылка на переменную среды, а всё, что связано с < или >, — это перенаправление, и обычно справляется с этим на 99%. Конечно, проблема остаётся в том, что скрипты не могут полагаться на доступность каких-либо Unix-утилит или на то, что какие-либо найденные утилиты имеют Unix-подобные аргументы командной строки.

Расширения и XS, в теории, могут быть скомпилированы любым пользователем с помощью бесплатных инструментов. На практике многие этого не делают, так как пользователи платформы Acorn привыкли к двоичным дистрибутивам. MakeMaker работает, но ни один доступный make не справляется с файлами make MakeMaker; даже если и когда это будет исправлено, отсутствие Unix-подобной оболочки вызовет проблемы с правилами makefile, особенно с такими строками, как cd sdbm && make all, и всем, что использует кавычки.

"RISC OS" — правильное название операционной системы, но значение в $^O — "riscos" (потому что нам не нравится кричать).

Другие Perl

Perl был портирован на многие платформы, которые не попадают ни в одну из вышеперечисленных категорий. Некоторые из них, такие как AmigaOS, QNX, Plan 9 и VOS, были хорошо интегрированы в стандартный набор исходного кода Perl. Возможно, вам нужно посмотреть в каталог ports/ на CPAN для получения информации и, возможно, двоичных файлов для таких как: aos, Atari ST, lynxos, riscos, Novell Netware, Tandem Guardian и т. д. (Да, мы знаем, что некоторые из этих ОС могут относиться к категории Unix, но мы не являемся организацией по стандартизации.)

Некоторые примерные имена операционных систем и их значения $^O в категории «OTHER» включают:

OS            $^O        $Config{archname}
------------------------------------------
Amiga DOS     amigaos    m68k-amigos

См. также:

  • Amiga, README.amiga (установлен как perlamiga).

  • Бесплатный perl5-базированный PERL.NLM для Novell Netware доступен в виде предварительно скомпилированного двоичного файла и исходного кода с http://www.novell.com/, а также с CPAN.

  • Plan 9, README.plan9

РЕАЛИЗАЦИИ ФУНКЦИЙ

Ниже приведены функции, которые либо не реализованы вообще, либо были реализованы по-разному на различных платформах. Перед каждым описанием будет (в скобках) список платформ, к которым относится описание.

Список может быть неполным или даже неверным в некоторых местах. В случае сомнений, обратитесь к файлам README для конкретной платформы в дистрибутиве исходного кода Perl и любым другим документационным ресурсам, сопровождающим данный порт.

Также имейте в виду, что даже среди Unix-подобных систем существуют различия.

END_OF_DOCUMENT_MARKER

Для многих функций также можно запросить %Config, экспортируемый по умолчанию из модуля Config. Например, чтобы проверить, имеет ли платформа вызов lstat, проверьте $Config{d_lstat}. См. Конфигурацию для полного описания доступных переменных.

Алфавитный список функций Perl

-X

(Win32) -w только проверяет атрибут файла только для чтения (FILE_ATTRIBUTE_READONLY), который определяет, может ли каталог быть удалён, а не может ли он быть записан. Каталоги всегда имеют права чтения и записи, если доступ не запрещён списками управления доступом (DACL).

(VMS) -r, -w, -x, и -o показывают, доступен ли файл, что может не отражать защиты файлов, основанные на UIC.

(RISC OS) -s по имени открытого файла вернёт выделенное пространство на диске, а не текущий объём. -s открытого дескриптора файла возвращает текущий размер.

(Win32, VMS, RISC OS) -R, -W, -X, -O неотличимы от -r, -w, -x, -o.

(Win32, VMS, RISC OS) -g, -k, -l, -u, -A не имеют особого смысла.

(VMS, RISC OS) -p не имеет особого смысла.

(VMS) -d истинно, если передаётся спецификация устройства без явного каталога.

(Win32) -x (или -X) определяют, заканчивается ли файл одним из исполняемых суффиксов. -S не имеет смысла.

(RISC OS) -x (или -X) определяют, имеет ли файл тип исполняемого файла.

alarm

(Win32) Эмулируется с помощью таймеров, которые необходимо явно опрашивать всякий раз, когда Perl хочет обработать «безопасные сигналы», и поэтому не могут прерывать блокирующие системные вызовы.

atan2

(Tru64, HP-UX 10.20) Из-за проблем с различными процессорами, математическими библиотеками, компиляторами и стандартами, результаты для atan2 могут варьироваться в зависимости от любой комбинации вышеперечисленного. Perl пытается соответствовать стандартам Open Group/IEEE для результатов, возвращаемых из atan2, но не может этого гарантировать, если система, на которой работает Perl, этого не позволяет.

Текущая версия стандартов для atan2 доступна по адресу http://www.opengroup.org/onlinepubs/009695399/functions/atan2.html.

binmode

(RISC OS) Не имеет смысла.

(VMS) Переоткрывает файл и восстанавливает указатель; если функция завершается неудачно, подлежащий дескриптор файла может быть закрыт, или указатель может находиться в другом положении.

(Win32) Значение, возвращаемое tell, может измениться после вызова, и дескриптор файла может быть сброшен.

chmod

(Win32) Подходит только для изменения доступа "владелец" чтение-запись; биты "группа" и "другие" не имеют смысла.

(RISC OS) Подходит только для изменения доступа "владелец" и "другие" чтение-запись.

(VOS) Разрешения доступа отображаются на изменения списка управления доступом VOS.

(Cygwin) Фактические разрешения зависят от значения переменной CYGWIN в системных настройках среды.

(Android) Установка бита exec в некоторых местах (обычно /sdcard) вернёт true, но фактически бит не будет установлен.

(VMS) Аргумент режима нуль устанавливает права доступа на значение по умолчанию для пользователя, а не отключает все права.

chown

(Plan 9, RISC OS) Не реализовано.

(Win32) Не делает ничего, но не завершится ошибкой.

(VOS) Немного необычно, так как понятие владения в VOS немного необычно.

chroot

(Win32, VMS, Plan 9, RISC OS, VOS) Не реализовано.

crypt

(Win32) Может отсутствовать, если библиотека или исходный код не были предоставлены при сборке Perl.

(Android) Не реализовано.

dbmclose

(VMS, Plan 9, VOS) Не реализовано.

dbmopen

(VMS, Plan 9, VOS) Не реализовано.

dump

(RISC OS) Не полезно.

(Cygwin, Win32) Не поддерживается.

(VMS) Вызывает отладчик VMS.

exec

(Win32) exec LIST без использования синтаксиса косвенного объекта (exec PROGRAM LIST) может перейти к попытке использовать оболочку, если первая spawn() завершится неудачей.

Обратите внимание, что форма списка exec() эмулируется, поскольку API Win32 CreateProcess() принимает простую строку, а не массив аргументов командной строки. Это может иметь последствия для безопасности вашего кода.

(SunOS, Solaris, HP-UX) Не автоматически сбрасывает дескрипторы вывода на некоторых платформах.

(Symbian OS) Не поддерживается.

exit

(VMS) Эмулирует Unix exit (который рассматривает exit 1 как индикатор ошибки) путём сопоставления 1 с SS$_ABORT (44). Это поведение может быть переопределено с помощью псевдонима use vmsish 'exit'. Как и функция CRTL exit(), exit 0 также сопоставляется со статусом выхода SS$_NORMAL (1); это сопоставление не может быть переопределено. Любой другой аргумент exit используется непосредственно как статус выхода Perl. В VMS, если не включён будущий режим POSIX_EXIT, код выхода всегда должен быть допустимым кодом выхода VMS, а не общим числом. Когда режим POSIX_EXIT включён, общее число будет закодировано в методе, совместимом с макросом C-библиотеки _POSIX_EXIT, чтобы его могли декодировать другие программы, особенно написанные на C, такие как пакет GNV.

(Solaris) exit сбрасывает указатели файлов, что является проблемой, когда вызывается из дочернего процесса (созданного функцией fork) в BEGIN. Обходной путь заключается в использовании POSIX::_exit.

exit unless $Config{archname} =~ /\bsolaris\b/;
require POSIX;
POSIX::_exit(0);
fcntl

(Win32) Не реализовано.

(VMS) Некоторые функции доступны в зависимости от версии VMS.

flock

(VMS, RISC OS, VOS) Не реализовано.

fork

(AmigaOS, RISC OS, VMS) Не реализовано.

(Win32) Эмулируется с использованием нескольких интерпретаторов. См. perlfork.

(SunOS, Solaris, HP-UX) Не автоматически сбрасывает дескрипторы вывода на некоторых платформах.

getlogin

(RISC OS) Не реализовано.

getpgrp

(Win32, VMS, RISC OS) Не реализовано.

getppid

(Win32, RISC OS) Не реализовано.

getpriority

(Win32, VMS, RISC OS, VOS) Не реализовано.

getpwnam

(Win32) Не реализовано.

(RISC OS) Не полезно.

getgrnam

(Win32, VMS, RISC OS) Не реализовано.

getnetbyname

(Android, Win32, Plan 9) Не реализовано.

getpwuid

(Win32) Не реализовано.

(RISC OS) Не полезно.

getgrgid

(Win32, VMS, RISC OS) Не реализовано.

getnetbyaddr

(Android, Win32, Plan 9) Не реализовано.

getprotobynumber

(Android) Не реализовано.

getpwent

(Android, Win32) Не реализовано.

getgrent

(Android, Win32, VMS) Не реализовано.

gethostbyname

(Irix 5) gethostbyname('localhost') не работает везде: возможно, вам придётся использовать gethostbyname('127.0.0.1').

gethostent

(Win32) Не реализовано.

getnetent

(Android, Win32, Plan 9) Не реализовано.

getprotoent

(Android, Win32, Plan 9) Не реализовано.

getservent

(Win32, Plan 9) Не реализовано.

seekdir

(Android) Не реализовано.

sethostent

(Android, Win32, Plan 9, RISC OS) Не реализовано.

setnetent

(Win32, Plan 9, RISC OS) Не реализовано.

setprotoent

(Android, Win32, Plan 9, RISC OS) Не реализовано.

setservent

(Plan 9, Win32, RISC OS) Не реализовано.

endpwent

(Win32) Не реализовано.

(Android) Либо не реализовано, либо это нет-операция.

endgrent

(Android, RISC OS, VMS, Win32) Не реализовано.

endhostent

(Android, Win32) Не реализовано.

endnetent

(Android, Win32, Plan 9) Не реализовано.

endprotoent

(Android, Win32, Plan 9) Не реализовано.

endservent

(Plan 9, Win32) Не реализовано.

getsockopt

(Plan 9) Не реализовано.

glob

Этот оператор реализован через расширение File::Glob на большинстве платформ. См. File::Glob для информации о переносимости.

gmtime

По теории, gmtime надёжен в диапазоне от -2**63 до 2**63-1. Однако, из-за обходных путей в реализации, использующих числа с плавающей точкой, точность будет снижаться по мере увеличения времени. Это ошибка, которая будет исправлена в будущем.

(VOS) Значения времени представляют собой 32-битные величины.

ioctl

(VMS) Не реализовано.

(Win32) Доступно только для дескрипторов сокетов, и выполняет то же, что и вызов ioctlsocket() в API Winsock.

(RISC OS) Доступно только для дескрипторов сокетов.

kill

(RISC OS) Не реализовано, поэтому не пригодно для проверки заражения.

(Win32) kill не отправляет сигнал идентифицированному процессу, как это делается на платформах Unix. Вместо этого kill($sig, $pid) завершает процесс, идентифицированный по $pid, и заставляет его немедленно выйти со статусом завершения $sig. Как и в Unix, если $sig равно 0 и указанный процесс существует, возвращается true, не завершая его.

(Win32) kill(-9, $pid) завершит процесс, указанный $pid, и рекурсивно все дочерние процессы, принадлежащие ему. Это отличается от семантики Unix, где сигнал будет передан всем процессам в той же группе процессов, что и процесс, указанный $pid.

(VMS) Значение pid = -1, указывающее на все процессы в системе, в настоящее время не поддерживается.

link

(RISC OS, VOS) Не реализовано.

(AmigaOS) Счётчик ссылок не обновляется, так как жёсткие ссылки не совсем жёсткие (они находятся где-то между жёсткими и мягкими ссылками).

(Win32) Жёсткие ссылки реализованы в Win32 под NTFS только. Они изначально поддерживаются в Windows 2000 и более поздних версиях. В Windows NT они реализованы с использованием поддержки подсистемы Windows POSIX, и Perl-процессу потребуются права администратора или оператора резервного копирования для создания жёстких ссылок.

(VMS) Доступно в 64-разрядном OpenVMS 8.2 и более поздних версиях.

localtime

localtime имеет тот же диапазон, что и "gmtime", но из-за изменения правил часовых поясов точность для исторических и будущих времён может снизиться, но обычно не более чем на час.

lstat

(RISC OS) Не реализовано.

(Win32) Возвращаемые значения (особенно для устройств и индексов) могут быть некорректными.

msgctl
msgget
msgsnd
msgrcv

(Android, Win32, VMS, Plan 9, RISC OS, VOS) Не реализовано.

open

(RISC OS) Режимы открытия |- и -| не поддерживаются.

(SunOS, Solaris, HP-UX) Открытие процесса не приводит к автоматической очистке выходных каналов на некоторых платформах.

(Win32) Оба режима |- и -| поддерживаются, но список имитируется, так как API Win32 CreateProcess() принимает простую строку, а не массив аргументов. Это может иметь последствия для безопасности вашего кода.

readlink

(Win32, VMS, RISC OS) Не реализовано.

rename

(Win32) Невозможно перемещать каталоги между каталогами на разных логических томах.

rewinddir

(Win32) Не заставит readdir повторно прочитать поток каталога. Записи, уже прочитанные до вызова rewinddir, просто будут возвращены из кэш-буфера.

select

(Win32, VMS) Реализовано только для сокетов.

(RISC OS) Надёжно только для сокетов.

Обратите внимание, что форма select FILEHANDLE обычно портативна.

semctl
semget
semop

(Android, Win32, VMS, RISC OS) Не реализовано.

setgrent

(Android, VMS, Win32, RISC OS) Не реализовано.

setpgrp

(Win32, VMS, RISC OS, VOS) Не реализовано.

setpriority

(Win32, VMS, RISC OS, VOS) Не реализовано.

setpwent

(Android, Win32, RISC OS) Не реализовано.

setsockopt

(Plan 9) Не реализовано.

shmctl
shmget
shmread
shmwrite

(Android, Win32, VMS, RISC OS) Не реализовано.

sleep

(Win32) Имитируется с использованием функций синхронизации, чтобы его можно было прервать с помощью alarm, и ограничен максимум 4294967 секундами, приблизительно 49 днями.

socketpair

(RISC OS) Не реализовано.

(VMS) Доступно в 64-разрядном OpenVMS 8.2 и более поздних версиях.

stat

Платформы, на которых нет rdev, blksize, или blocks, вернут их как '', поэтому числовое сравнение или обработка этих полей могут привести к предупреждениям «не число».

(Mac OS X) ctime не поддерживается в UFS.

(Win32) ctime — это время создания, а не время изменения индекса.

(Win32) dev и ino не имеют смысла.

(VMS) dev и ino не обязательно надёжны.

(RISC OS) mtime, atime и ctime возвращают последнее время изменения. dev и ino не обязательно надёжны.

(OS/2) dev, rdev, blksize, и blocks недоступны. ino не имеет смысла и будет отличаться между вызовами stat для одного и того же файла.

(Cygwin) Некоторые версии cygwin при поиске stat("foo") и его отсутствии могут попытаться stat("foo.exe").

(Win32) stat нужно открыть файл, чтобы определить счётчик ссылок и обновить атрибуты, которые могли быть изменены через жёсткие ссылки. Установка ${^WIN32_SLOPPY_STAT} в значение true ускоряет stat за счёт отказа от выполнения этой операции.

symlink

(Win32, RISC OS) Не реализовано.

(VMS) Реализовано в 64-битном VMS 8.3. VMS требует, чтобы символическая ссылка имела синтаксис Unix, если она должна разрешаться в действительный путь.

syscall

(Win32, VMS, RISC OS, VOS) Не реализовано.

sysopen

(Mac OS, OS/390) Традиционные 0, 1, и 2 режимы реализованы с разными числовыми значениями на некоторых системах. Однако флаги, экспортированные Fcntl (O_RDONLY, O_WRONLY, O_RDWR), должны работать везде.

system

(Win32) В целях оптимизации может не вызывать оболочку, указанную в $ENV{PERL5SHELL}. system(1, @args) запускает внешний процесс и немедленно возвращает его идентификатор процесса, не дожидаясь его завершения. Возвращаемое значение можно использовать впоследствии в wait или waitpid. Невозможность spawn() дочернего процесса обозначается установкой $? в значение 255 << 8. $? устанавливается в соответствии с Unix (т. е. статус выхода дочернего процесса получается с помощью $? >> 8, как описано в документации).

Обратите внимание, что список форм system() имитируется, так как API Win32 CreateProcess() принимает простую строку, а не массив аргументов командной строки. Это может иметь последствия для безопасности вашего кода.

(RISC OS) Нет оболочки для обработки метасимволов, и стандартное поведение — передача командной строки, завершающейся "\n", "\r" или "\0", запущенной программе. Перенаправление, например, > foo, выполняется (если вообще выполняется) библиотекой времени выполнения запущенной программы. system LIST вызовет эмуляцию exec библиотеки эмуляции Unix, которая попытается смоделировать stdin, stdout, stderr родителя, при условии, что дочерняя программа использует совместимую версию библиотеки эмуляции. system SCALAR вызовет родную командную строку напрямую, и такая эмуляция дочерней программы Unix не произойдёт. Результаты могут быть различными.

(Win32) system LIST без использования синтаксиса косвенного объекта (system PROGRAM LIST) может вернуться к попытке вызова оболочки, если первая spawn() попытка провалится.

(SunOS, Solaris, HP-UX) Не приводит к автоматической очистке выходных каналов на некоторых платформах.

(VMS) Как и в Win32, system(1, @args) запускает внешний процесс и немедленно возвращает его идентификатор процесса без ожидания его завершения. В этом случае возвращаемое значение может быть использовано впоследствии в wait или waitpid. В противном случае возвращаемое значение имеет сходство с POSIX (сдвинуто на 8 битов), что позволяет только предполагаемое значение, полученное из битов серьёзности родного 32-битного кода состояния (если не переопределено use vmsish 'status'). Если родной код состояния имеет закодированное значение POSIX, значение POSIX будет декодировано для получения ожидаемого выходного значения. Подробности см. в "$?" в perlvms.

telldir

(Android) Не реализовано.

times

(Win32) «Кумулятивные» времена будут неверными. На платформах, отличных от Windows NT или Windows 2000, время «системы» будет неверным, а время «пользователя» фактически будет временем, возвращаемым функцией clock() в библиотеке C.

(RISC OS) Не имеет практического применения.

truncate

(Более старые версии VMS) Не реализовано.

(VOS) Обрезка только до тех же или более коротких длин.

(Win32) Если предоставлен FILEHANDLE, он должен быть доступным для записи и открытым в режиме добавления (т.е., используйте open(my $fh, '>>', 'filename') или sysopen(my $fh, ..., O_APPEND|O_RDWR). Если предоставлено имя файла, он не должен быть открыт в другом месте.

umask

Возвращает undef в случае недоступности.

(AmigaOS) umask работает, но правильные разрешения устанавливаются только при окончательном закрытии файла.

utime

(VMS, RISC OS) Обновляется только время изменения.

(Win32) Может не вести себя ожидаемым образом. Поведение зависит от реализации C-библиотеки utime() и используемой файловой системы. Файловая система FAT обычно не поддерживает поле «время доступа» и может ограничивать временные метки разрешением в две секунды.

wait
waitpid

(Win32) Может применяться только к дескрипторам процессов, возвращаемых для процессов, запущенных с помощью system(1, ...) или псевдопроцессов, созданных с помощью fork.

(RISC OS) Не полезно.

Поддерживаемые платформы

Известно, что следующие платформы поддерживают компиляцию Perl 5.12 (по состоянию на апрель 2010 года, дата выпуска) из стандартного исходного кода, доступного по адресу http://www.cpan.org/src

Linux (x86, ARM, IA64)
HP-UX
AIX
Win32
Windows 2000
Windows XP
Windows Server 2003
Windows Vista
Windows Server 2008
Windows 7
Cygwin

Некоторые тесты известны тем, что не проходят:

  • ext/XS-APItest/t/call_checker.t - см. https://rt.perl.org/Ticket/Display.html?id=78502

  • dist/I18N-Collate/t/I18N-Collate.t

  • ext/Win32CORE/t/win32core.t - может не пройти на недавних установках cygwin.

Solaris (x86, SPARC)
OpenVMS
Alpha (7.2 и новее)
I64 (8.2 и новее)
Symbian
NetBSD
FreeBSD
Debian GNU/kFreeBSD
Haiku
Irix (6.5. Что ещё?)
OpenBSD
Dragonfly BSD
Midnight BSD
QNX Neutrino RTOS (6.5.0)
MirOS BSD
Stratus OpenVOS (17.0 или новее)

Ограничения:

Вопросы с time_t, которые могут быть или не быть исправлены
Symbian (Series 60 v3, 3.2 и 5 — что ещё?)
Stratus VOS / OpenVOS
AIX
Android
FreeMINT

Perl теперь компилируется с FreeMiNT/Atari. Несколько тестов не проходят, что требует дальнейшего изучения.

Порт FreeMiNT использует GNU dld для возможностей модулей загрузки. Поэтому убедитесь, что эта библиотека установлена при компиляции perl.

Платформы с окончанием жизненного цикла

(Perl 5.20)

Следующие платформы поддерживались предыдущей версией Perl, но официально удалены из исходного кода Perl начиная с 5.20:

AT&T 3b1

(Perl 5.14)

Следующие платформы поддерживались до 5.10. Они могли по-прежнему работать в 5.12, но поддерживающий код был удалён для 5.14:

Windows 95
Windows 98
Windows ME
Windows NT4

(Perl 5.12)

Следующие платформы поддерживались предыдущей версией Perl, но официально удалены из исходного кода Perl начиная с 5.12:

Atari MiNT
Apollo Domain/OS
Apple Mac OS 8/9
Tenon Machten

Поддерживаемые платформы (Perl 5.8)

По состоянию на июль 2002 года (выпуск Perl 5.8.0), следующие платформы могли компилировать Perl из стандартного исходного кода, доступного по адресу http://www.cpan.org/src/

AIX
BeOS
BSD/OS          (BSDi)
Cygwin
DG/UX
DOS DJGPP       1)
DYNIX/ptx
EPOC R5
FreeBSD
HI-UXMPP        (Hitachi) (5.8.0 worked but we didn't know it)
HP-UX
IRIX
Linux
Mac OS Classic
Mac OS X        (Darwin)
MPE/iX
NetBSD
NetWare
NonStop-UX
ReliantUNIX     (formerly SINIX)
OpenBSD
OpenVMS         (formerly VMS)
Open UNIX       (Unixware) (since Perl 5.8.1/5.9.0)
OS/2
OS/400          (using the PASE) (since Perl 5.8.1/5.9.0)
POSIX-BC        (formerly BS2000)
QNX
Solaris
SunOS 4
SUPER-UX        (NEC)
Tru64 UNIX      (formerly DEC OSF/1, Digital UNIX)
UNICOS
UNICOS/mk
UTS
VOS / OpenVOS
Win95/98/ME/2K/XP 2)
WinCE
z/OS            (formerly OS/390)
VM/ESA

1) in DOS mode either the DOS or OS/2 ports can be used
2) compilers: Borland, MinGW (GCC), VC6

Следующие платформы работали с предыдущими выпусками (5.6 и 5.7), но нам не удалось либо исправить, либо протестировать их вовремя для выпуска 5.8.0. Существует очень большая вероятность, что многие из них будут работать нормально с 5.8.0.

BSD/OS
DomainOS
Hurd
LynxOS
MachTen
PowerMAX
SCO SV
SVR4
Unixware
Windows 3.1

Известно, что они не работают с 5.8.0 (но могут работать с 5.6.1 и 5.7.2):

AmigaOS 3

Следующие платформы были известны тем, что компилировали Perl из исходного кода в прошлом (5.005_03 и ранее), но мы не смогли проверить их состояние для текущего выпуска, либо потому, что аппаратные/программные платформы редкие, либо потому, что у нас нет активного сторонника на этих платформах — или то и другое. Тем не менее, они работали раньше, поэтому попробуйте их скомпилировать и сообщите о любых проблемах по адресу https://github.com/Perl/perl5/issues.

3b1
A/UX
ConvexOS
CX/UX
DC/OSx
DDE SMES
DOS EMX
Dynix
EP/IX
ESIX
FPS
GENIX
Greenhills
ISC
MachTen 68k
MPC
NEWS-OS
NextSTEP
OpenSTEP
Opus
Plan 9
RISC/os
SCO ODT/OSR
Stellar
SVR2
TI1500
TitanOS
Ultrix
Unisys Dynix

Для следующих платформ существуют свои собственные дистрибутивы исходного кода и двоичных файлов, доступные по адресу http://www.cpan.org/ports/

                        Perl release

OS/400 (ILE)            5.005_02
Tandem Guardian         5.004

Для следующих платформ доступны только двоичные файлы по адресу http://www.cpan.org/ports/index.html :

                        Perl release

Acorn RISCOS            5.005_02
AOS                     5.002
LynxOS                  5.004_02

Хотя мы рекомендуем всегда строить собственный Perl из исходного кода, как для максимальной конфигурируемости, так и для безопасности, в случае необходимости вы можете проверить наличие двоичных дистрибутивов по адресу http://www.cpan.org/ports/index.html.

См. также

perlaix, perlamiga, perlbs2000, perlce, perlcygwin, perldos, perlebcdic, perlfreebsd, perlhurd, perlhpux, perlirix, perlmacos, perlmacosx, perlnetware, perlos2, perlos390, perlos400, perlplan9, perlqnx, perlsolaris, perltru64, perlunicode, perlvms, perlvos, perlwin32 и Win32.

Авторы / Соавторы

Abigail <abigail@abigail.be>, Charles Bailey <bailey@newman.upenn.edu>, Graham Barr <gbarr@pobox.com>, Tom Christiansen <tchrist@perl.com>, Nicholas Clark <nick@ccl4.org>, Thomas Dorner <Thomas.Dorner@start.de>, Andy Dougherty <doughera@lafayette.edu>, Dominic Dunlop <domo@computer.org>, Neale Ferguson <neale@vma.tabnsw.com.au>, David J. Fiander <davidf@mks.com>, Paul Green <Paul.Green@stratus.com>, M.J.T. Guy <mjtg@cam.ac.uk>, Jarkko Hietaniemi <jhi@iki.fi>, Luther Huffman <lutherh@stratcom.com>, Nick Ing-Simmons <nick@ing-simmons.net>, Andreas J. König <a.koenig@mind.de>, Markus Laker <mlaker@contax.co.uk>, Andrew M. Langmead <aml@world.std.com>, Lukas Mai <l.mai@web.de>, Larry Moore <ljmoore@freespace.net>, Paul Moore <Paul.Moore@uk.origin-it.com>, Chris Nandor <pudge@pobox.com>, Matthias Neeracher <neeracher@mac.com>, Philip Newton <pne@cpan.org>, Gary Ng <71564.1743@CompuServe.COM>, Tom Phoenix <rootbeer@teleport.com>, André Pirard <A.Pirard@ulg.ac.be>, Peter Prymmer <pvhp@forte.com>, Hugo van der Sanden <hv@crypt0.demon.co.uk>, Gurusamy Sarathy <gsar@activestate.com>, Paul J. Schinder <schinder@pobox.com>, Michael G Schwern <schwern@pobox.com>, Dan Sugalski <dan@sidhe.org>, Nathan Torkington <gnat@frii.com>, John Malmberg <wb8tyw@qsl.net>

© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.30.3/perlport

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API