Типичные программы Unix / Linux принимают входные данные командной строки в качестве аргумента count ( int argc
) и аргумента vector ( char *argv[]
). Первым элементом argv
является имя программы, за которым следуют фактические аргументы.
Почему имя программы передается исполняемому файлу в качестве аргумента? Есть ли примеры программ, использующих свое имя (может быть, какая-то exec
ситуация)?
command-line
c
arguments
Shrikant Giridhar
источник
источник
sh
есть символическая ссылка наdash
. Они ведут себя по-разному, когда их называют какsh
или какdash
busybox
(обычно на спасательных дисках и т. Д.), То почти все (cp, mv, rm, ls, ...) является символической ссылкой на busybox.gcc
,bash
,gunzip
, большую часть остальной части ОС ...), так как Linux это только ядро.Ответы:
Для начала обратите внимание, что
argv[0]
это не обязательно название программы. Это то , что вызывающий абонент вводит вargv[0]
частьexecve
системного вызова (например , см этот вопрос на переполнение стека ). (Все остальные вариантыexec
являются не системными вызовами, а интерфейсамиexecve
.)Предположим, например, следующее (используя
execl
):/var/tmp/mybackdoor
это то, что выполняется, ноargv[0]
установленоtop
, и это то, чтоps
или (реальный)top
будет отображаться. Смотрите этот ответ на U & L SE для получения дополнительной информации об этом.Установка все это в стороне: До появления фантазии файловых систем , таких как
/proc
,argv[0]
был единственным способом для процесса , чтобы узнать о его собственном имени. Для чего это будет хорошо?источник
bunzip2
,bzcat
иbzip2
, для которых первые две являются символическими ссылками на третью.zcat
это не символическая ссылка. Кажется, они избегают недостатков этой техники, используя вместо этого сценарий оболочки. Но они не могут распечатать полный--help
вывод, потому что кто-то, кто добавил опции в gzip, тоже забыл поддерживать zcat.gunzip
это историческое исключение.argv[0]
в свои выходные данные использования / помощи вместо жесткого кодирования их имени. Некоторые полностью, некоторые просто базовое имя.Много:
argv[0]
естьsh
. Он запускается как оболочка входа в систему, когдаargv[0]
начинается с-
.vi
,view
,evim
,eview
,ex
,vimdiff
и т.д.shutdown
,reboot
и т.д. являются символическими ссылками наsystemctl
.источник
sendmail
иmail
. Каждый Unix MTA поставляется с символической ссылкой для этих двух команд и предназначен для имитации поведения оригинала при вызове как такового, что означает, что любая Unix-программа, которая должна отправлять почту, точно знает, как они могут это сделать.test
и[
: когда вы вызываете первый, он обрабатывает ошибку, если последний аргумент равен]
. (в реальной стабильной версии Debian эти команды представляют собой две разные программы, но предыдущие версии и MacO все еще используют одну и ту же программу). Иtex
,latex
и так далее: бинарная то же самое, но , глядя , как его называли, это выбрать правильный конфигурационный файл.init
похож.[
считает ошибкой, если последний аргумент не является]
.Исторически,
argv
это просто массив указателей на «слова» командной строки, поэтому имеет смысл начать с первого «слова», которое, как оказалось, является названием программы.И есть довольно много программ, которые ведут себя по-разному, в зависимости от того, какое имя используется для их вызова, так что вы можете просто создавать разные ссылки на них и получать разные «команды». Самый экстремальный пример, который я могу вспомнить, это busybox , который действует как несколько десятков различных «команд» в зависимости от того, как он вызывается .
Изменить : ссылки на Unix 1-е издание, по запросу
Можно увидеть, например, из основной функции
cc
этогоargc
иargv
уже были использованы. В оболочках копируют аргументыparbuf
внутриnewarg
части петли, в то время как лечащие сама команда таким же образом , как аргументы. (Конечно, позже он выполняет только первый аргумент, который является именем команды). Похоже,execv
родственников тогда не было.источник
exec
берет имя команды для выполнения и массив нулевых символов с указателями на символы (лучше всего смотреть на minnie.tuhs.org/cgi-bin/utree.pl?file=V1/u0.s , гдеexec
принимает ссылки на метку 2 и метку 1, и на метке2:
появляетсяetc/init\0
, а на метке1:
появляется ссылка на метку 2 и завершающий ноль), что в основном то,execve
что сегодня делает минусenvp
.execv
иexecl
существовали «вечно» (то есть с начала до середины 1970-х годов) - этоexecv
был системный вызов иexecl
была библиотечная функция, которая его вызывала.execve
тогда не существовало, потому что тогда среды не было. Другие члены семьи были добавлены позже.execv
источник v1, на который я ссылался? Просто любопытно.Сценарии использования:
Вы можете использовать имя программы, чтобы изменить ее поведение .
Например, вы можете создать несколько символических ссылок на настоящий двоичный файл.
Одним из известных примеров использования этого метода является проект busybox, который устанавливает только один двоичный файл и множество символических ссылок на него. (ls, cp, mv и т. д.). Они делают это, чтобы сэкономить место для хранения, потому что их целью являются небольшие встроенные устройства.
Это также используется в
setarch
util-linux:Здесь они используют эту технику в основном, чтобы избежать дублирования исходных файлов или просто сделать источники более читабельными.
Другой вариант использования - это программа, которая должна загружать некоторые модули или данные во время выполнения. Наличие пути к программе позволяет вам загружать модули с пути относительно места расположения программы .
Более того, многие программы печатают сообщения об ошибках, включая название программы .
Почему :
man 3p execve
):Обратите внимание, что в стандарте C написано «имя программы», а не «имя файла».
источник
В дополнение к программам, изменяющим их поведение в зависимости от того, как они были вызваны, я считаю
argv[0]
полезным печатать информацию об использовании программы, например:Это заставляет сообщение об использовании всегда использовать имя, через которое оно было вызвано. Если программа переименована, сообщение об использовании меняется вместе с ней. Он даже включает имя пути, с которым он был вызван:
Это приятное прикосновение, особенно для небольших специальных инструментов / скриптов, которые могут жить повсюду.
Это кажется обычной практикой в инструментах GNU, см.
ls
Например:источник
Один выполняет программу набрав:
program_name0 arg1 arg2 arg3 ...
.Таким образом, оболочка должна разделить токен, а первый токен - это уже имя программы. И кстати, так что есть одинаковые показатели на стороне программы и на оболочке.
Я думаю, что это был просто удобный прием (в самом начале), и, как вы видите в других ответах, он также был очень удобен, поэтому эта традиция была продолжена и установлена как API.
источник
По сути, argv включает в себя имя программы, так что вы можете писать сообщения об ошибках, например
prgm: file: No such file or directory
, которые будут реализованы примерно так:источник
Другим примером применения этого является эта программа, которая заменяет себя на ... себя, пока вы не наберете что-то, что не является
y
.Очевидно, что это своего рода надуманный, но интересный пример, но я думаю, что это может иметь реальное применение - например, самообновляемый двоичный файл, который переписывает свое собственное пространство памяти с новой версией самого себя, которую он загрузил или изменил.
Пример:
Источник и еще немного информации .
источник
Путь к программе таков
argv[0]
, чтобы программа могла получить файлы конфигурации и т. Д. Из каталога установки.Это было бы невозможно без
argv[0]
.источник
(char *path_to_program, char **argv, int argc)
например~/.<program>
,/etc/<program
,$XDG_CONFIG_HOME
) и либо принять параметр , чтобы изменить его или иметь опцию во время компиляции , что печет в постоянной к двоичной системе .ccache ведет себя так, чтобы имитировать различные вызовы двоичных файлов компилятора. ccache - это кеш компиляции - суть в том, чтобы никогда не компилировать один и тот же исходный код дважды, а вместо этого возвращать объектный код из кеша, если это возможно.
На странице справочника ccache «есть два способа использования ccache. Вы можете либо добавить префиксные команды компиляции к ccache, либо разрешить маскировать ccache в качестве компилятора, создав символическую ссылку (называемую как компилятор) для ccache. Первый метод Это наиболее удобно, если вы просто хотите попробовать ccache или использовать его для некоторых конкретных проектов. Второй способ наиболее полезен, когда вы хотите использовать ccache для всех ваших компиляций. "
Метод символических ссылок включает в себя выполнение этих команд:
... эффект которого состоит в том, что ccache позволяет захватывать любые команды, которые в противном случае пошли бы в компиляторы, что позволяет ccache возвращать кэшированный файл или передавать команду фактическому компилятору.
источник