Как запустить скрипт Python без указания расширения файла (кроссплатформенное решение)? - PullRequest
8 голосов
/ 27 февраля 2010

Допустим, у нас есть скрипт Python do.py, и мы хотим, чтобы его можно было вызывать без расширения, например do или ./do.

Если мы переименуем файл с do.py на do и убедимся, что у нас есть действительная строка shebang, он будет работать для всех платформ, кроме Windows. В Windows нет способа выполнить файл без расширения.

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

Похоже, нам нужно доставить один и тот же сценарий под двумя разными именами, чтобы он вызывался в средах Windows и не Windows Мне действительно это не нравится, и я ищу решение без этой избыточности.

Другой распространенный подход - добавить пакетный файл оболочки do.cmd, который вызывает исходный файл do.py. В этом есть по крайней мере одна серьезная проблема: он ломает Ctrl + C / Ctrl + Break , потому что нет способа помешать cmd.exe вызвать вас с Завершить пакетное задание? (Да / Нет) сообщение.

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

  • вернуть код ошибки (errorlevel), возвращенный исходным скриптом
  • это не изменит среду
  • будет повторно использовать ту же консоль (без новых окон)
  • не мешает STDOUT, STDIN или STDERR
  • дружить с Ctrl-C (без подсказок)

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

Ответы [ 6 ]

5 голосов
/ 27 февраля 2010

В Windows я добавил расширение «.py» в переменную среды «PATHEXT», и это работает для меня - если файл .py хранится в каталоге, который является частью переменной среды «PATH».

C:\>echo %PATHEXT%
.COM;.EXE;.BAT;.CMD;.PY;.JS;.JSE
4 голосов
/ 28 августа 2010

Напишите ваш основной модуль Python с расширением .py.Установите PATHEXT правильно, и он будет работать в Windows без необходимости вводить расширение.

В Unix напишите вторую программу на Python, которая просто импортирует первую, используя синтаксис she-bang.Нет расширения для этого файла - это сценарий оболочки.Например:

#!/usr/bin/env python
import do

Это приведет к импорту do.py.

Только do должен быть помечен как исполняемый для Unix.do.py - это модуль в этой среде.

Когда вы импортируете модуль, код в модуле запускается один раз.

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

2 голосов
/ 27 февраля 2010

До сих пор я придумал это решение, которое работает. Создайте файл yourname.py с таким содержанием:

import os, sys
filename = os.path.splitext(os.path.basename(sys.argv[0]))[0]
if not os.path.exists(filename):
    # filename does not exists, we will emulate cmd behaviour
    sys.stderr.write("'%s' is not recognized as an internal or external command,\noperable program or batch file." % filename)
    sys.exit(9009)
ret = os.system("python %s %s" % (
        filename,
        " ".join(sys.argv[1:])
        ))
exit(ret)
1 голос
/ 27 февраля 2010

Вы можете использовать distutils для установки скриптов в установку Python (например, устанавливается средство easy_install).

Для Windows вы можете использовать py2exe для создания сценария, который может выполняться без расширения файла. В Linux вы можете просто использовать файл без расширения, но со строкой shebang.

0 голосов
/ 25 февраля 2014

Ответ Джейсона яснее и проще, но общая версия получает имя модуля из имени файла:

#!/usr/bin/env python
import importlib, os, sys
importlib.import_module(os.path.basename(sys.argv[0]))

Сказав это, я предпочитаю Джейсона, где сразу понятно, что происходит:

#!/usr/bin/env python
import do
0 голосов
/ 27 февраля 2010

вы всегда можете вызвать свой скрипт с помощью интерпретатора Python.Вы получаете такую ​​же согласованность в * nix, когда используете интерпретатор.

Windows

c:\> python c:\path\to\myscript 

* nix

$ python /path/to/myscript

Если это не то, что вам нужно, тогдая неправильно понимаю ваш вопрос.

...