Как сделать python или perl script переносимым как в linux, так и в windows?

Мне было интересно, как сделать python script переносимым для Linux и Windows?

Одна проблема, которую я вижу, это shebang. Как написать shebang так, чтобы script можно было запускать как в окнах, так и в linux?

Есть ли другие проблемы, кроме shebang, которые я должен знать?

Решение такое же для perl script?

Спасибо и приветствую!

Ответ 1

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

Существует много бит и частей, которые являются специфичными для платформы (многие из них существуют только в Unix, msvcrt только для Windows), поэтому, если вы хотите быть портативными, вы должны воздерживаться от них; некоторые из них немного отличаются (например, подробное точное поведение subprocess.Popen или mmap) - все это довольно продвинутый материал, и документы будут направлять вас туда. Если вы выполняете (через subprocess или иначе) внешние команды, вы должны убедиться, что они существуют на обеих платформах, конечно, или проверить, на какой платформе вы находитесь, и использовать разные внешние команды в каждом случае.

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

Я думаю, что об этом...

Ответ 2

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

$path = File::Spec->catfile("dir1", "dir2", "file")

Помните, что в Windows есть тома:

($volume, $path, $file) = File::Spec->splitpath($full_path);
@directories = File::Spec->splitdir($path);

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

$full_command = 'C:\Documents and Settings/program.exe "arg1" arg2'; # spaces alert!
system($full_command);

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

system('C:\Documents and Settings/program.exe', 'arg1', 'arg2');

Там есть набор переносимых нитей, задокументированных в руководстве perlport.

Ответ 3

Строка shebang будет интерпретироваться как комментарий Perl или Python. Единственное, что присваивает ему особое значение, это оболочка UNIX/Linux; он игнорируется в Windows. Способ, которым Windows знает, какой интерпретатор будет использовать для запуска файла, связан с файловыми ассоциациями в реестре, совсем другим механизмом.

Ответ 4

Я не знаю достаточно, чтобы прокомментировать подходы Python к этой проблеме, поэтому я не буду.

Большинство вещей в Perl будут работать. Есть несколько ошибок, которые легко избежать.

Вот несколько вещей, с которыми я столкнулся в годы работы с Win32 Perl:

  • Используйте форму 3 аргумента open. У двух форм аргумента могут быть проблемы с пробелами в путях. (Вы все равно должны делать это.)
  • Убедитесь, что корпус правильно, если вы используете модуль. use Warnings; будет работать, но на самом деле он потерпит неудачу.
  • select работает только в реальных сокетах под Windows. Вы не можете использовать его на любом другом дескрипторе.
  • Используйте File::Spec для управления путями к файлам.
  • При открытии дескриптора файла CRLF автоматически преобразуется в конец строки LF при чтении дескриптора. LF изменяется на CRLF при записи. Если вы хотите этого избежать, используйте binmode в ручке, чтобы предотвратить перевод.
  • Если вам нужно передать аргументы через оболочку, поместите двойные кавычки вокруг каждого аргумента. Это предотвратит ошибки из-за пробелов в именах файлов.

Подробнее о отдельных функциях см. perlport.