Здесь мы должны дважды передать имя файла в функции.
Они не совсем то же самое, что вы заметили, заметив, что один из них используется в качестве argv[0]
значения. Это не должно совпадать с базовым именем исполняемого файла; многие / большинство вещей игнорируют это, и вы можете положить туда все, что захотите.
Первый - это фактический путь к исполняемому файлу, для которого есть очевидная необходимость. Второй передается процессу якобы как имя, используемое для его вызова, но, например:
execl("/bin/ls", "banana", "-l", NULL);
Будет работать нормально, если предположить, что /bin/ls
это правильный путь.
Некоторые приложения, однако, используют argv[0]
. Обычно они имеют одну или несколько символических ссылок $PATH
; это распространено в утилитах сжатия (иногда они используют оболочки оболочки). Если вы xz
установили, stat $(which xzcat)
показывает, что это ссылка xz
, и man xzcat
это то же самое, man xz
что объясняет, что «xzcat эквивалентен xz --decompress --stdout». Способ, которым xz может сказать, как он был вызван, - проверка argv[0]
, делающая эти эквиваленты:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
busybox
может быть то, что вы хотите, чтобы это было в зависимости от того, как вы это называете правильно?/bin/ls
был busybox, он не знал бы, как выполнитьbanana
!Вам не нужно передавать имя файла дважды.
Первый - это файл, который на самом деле исполняется.
Вторым аргументом является то, каким должен быть
argv[0]
процесс, то есть то, что процесс должен видеть в качестве своего имени. Например, если вы запускаетеls
из оболочки, первый аргумент/bin/ls
, а второй простоls
.Вы можете выполнить определенный файл и вызвать его как-нибудь через второй аргумент; программа может проверить свое имя и вести себя по-разному в зависимости от имени. Это также может быть сделано через жесткие ссылки (или символические ссылки), но этот способ дает большую гибкость.
источник
argv[0]
имя ссылки.Вывод, который
argv[0]
может быть установлен на что угодно (в том числеNULL
). По соглашению ,argv[0]
будет установлен путь, по которому исполняемый файл был запущен (процессом оболочки, когда он это делаетexecve()
).Если
./foo
иdir/bar
это две разные ссылки (жесткие или символические) в том же исполняемый файл, а затем запустить программу из командной строки с помощью двух путей будет установленargv[0]
в./foo
иdir/bar
, соответственно.То, что
argv[0]
может бытьNULL
, часто упускается из виду.NULL
argv[0]
Например, следующий код может привести к сбою (хотя вместо этого glibc печатает что-то вроде <null>argv[0]
):Альтернативой в Linux является использование
/proc/self/exe
для таких случаев.источник
./foo
и один раз какdir/bar
.argv[0]
будет отличаться для этих двух случаев (в каждом случае он будет таким же, как путь, который вы использовали).argv[0]
что угодно, когдаexec*()
сами программируете. Это оболочка, которая устанавливаетargv[0]
путь, который использовался для запуска программы (и разумно делать то же самое, когда выexec*()
работаете с программой, поскольку многие программы проверяютargv[0]
и ожидают, что она будет содержать путь).