Этот вопрос навеян комментариями в Почему я получаю сообщение об ошибке «execv(file, args)» при использовании execl()?.
Когда мы используем
os.execl(sys.executable, "python", "script.py")
Второй параметр мне кажется избыточным, может кто-нибудь объяснить, зачем нужен этот параметр?
Первым аргументом работающей программы по соглашению является имя программы, введенное пользователем. Это не обязательно должно быть фактическое имя исполняемого файла, и часто это не так, например, когда файл находится в каталоге $PATH
.
Этому соглашению следуют большинство оболочек, но оно не применяется на уровне API.
В старые добрые времена без графических мониторов и без мышей текстовая консоль (или даже телетайп) была единственным пользовательским интерфейсом между пользователем и операционной системой.
Этот интерфейс (Command Line Interface, CLI) вместо современного GUI (Graphical User Interface) заставлял пользователя писать команды, в том числе для запуска исполняемых файлов, вместо нажатия на их иконки.
(Большинство существующих операционных систем все еще имеют эту возможность, например, окно командной строки или PowerShell в Windows или окно консоли/терминала в GNU/Linux.)
Командная строка для запуска программы имела/имеет вид
program argument1 argument2 ...
где program
(в те старые времена были только «программы» и «программисты», никаких «приложений» и «разработчиков») — имя исполняемого файла, часто включающее относительный/абсолютный путь.
Операционная система запускала program
, передавая ему не только аргументы (argument1
, argument2
, ...), но — в качестве так называемого 0th аргумента — и сам program
.
(В том же виде, в каком был набран, т.е. с путем или без, с суффиксом/расширением или без.)
Таким образом, запущенная программа может узнать, как она была запущена. Он может использовать эту информацию для различных целей, например
запретить запуск с другим именем ("nomen est omen") — значит, если вы переименовали исполняемый файл, вам не повезло,
для достижения различного поведения в зависимости от имени запуска (некоторые исполняемые файлы были / установлены с программными ссылками с разными именами),
для получения местоположения вспомогательных/пользовательских файлов из пути, если он явно использовался в команде.
Многие современные программы (о нет, приложения) все еще используют возможность запуска их из CLI с аргументами, но (в основном) игнорируют имя программы.
Например, в Windows вы можете использовать команду
notepad somename.txt
для запуска Блокнота с уже открытым файлом somename.txt
. Или — чтобы не уходить далеко — Python может запустить ваш скрипт командой
python somescript.py
Вернемся к основному вопросу:
Функция os.execl()
имитирует поведение запуска приложения из CLI, предоставляя пользователю (этой функции) возможность указать program
по своему усмотрению. Это второй параметр функции os.execl()
. Как я уже упоминал, от этого зависит поведение некоторых — в основном старых — программ.
Приложение:
В списке sys.argv
Python есть все параметры командной строки, включая аргумент 0th в элементе sys.argv[0]
.
Но учтите — если вы запустите свой скрипт командой
python /somefolder/somescript.py xxx 7
с точки зрения самого python
(нам не интересного) аргументы таковы:
"python"
,"/somefolder/somescript.py"
,"xxx"
,"7"
,но с точки зрения somescript.py
— то есть того, что получит ваш скрипт — аргументы
"/somefolder/somescript.py"
— она находится в sys.argv[0]
,"xxx"
— она находится в sys.argv[1]
,"7"
— она находится в sys.argv[2]
.