В среде C/Unix, в которой я работаю, некоторые разработчики используют __progname вместо argv [0] для сообщений use(). Есть ли некоторые преимущества? В чем разница между __progname и argv [0]. Это переносимо?Использование '__progname' вместо argv [0]
ответ
__progname
не является стандартным и, следовательно, не переносным, предпочитают argv[0]
. Я полагаю, что __progname
может искать строковый ресурс, чтобы получить имя, которое не зависит от имени файла, в котором вы его запускали. Но argv[0]
даст вам имя, которое они на самом деле запустили его, как я нашел бы более полезным.
Использование __progname
позволяет изменять содержимое массива argv[]
, сохраняя при этом имя программы. Некоторые из обычных инструментов, таких как getopt()
, изменяют argv[]
, поскольку они обрабатывают аргументы.
Для портативности вы можете strcopy argv[0]
в свой собственный буфер progname
, когда ваша программа запустится.
GNU getopt() messes with argv; версии, не относящиеся к GNU, обычно не делают этого. – 2008-11-08 08:43:20
Это BSDism, и определенно не переносимый.
Если ваша программа была запущена с использованием, например, символической ссылки, argv [0] будет содержать имя этой ссылки.
Я предполагаю, что __progname будет содержать имя фактического файла программы.
В любом случае argv [0] определяется стандартом C. __progname нет.
Я вижу по крайней мере две потенциальные проблемы с argv [0].
Во-первых, argv [0] или argv сам может быть NULL, если вызывающий пользователь execve() был злым или небрежным. Вызов execve («foobar», NULL, NULL) обычно является простым и интересным способом доказать над уверенным программистом, что его код не является сиг-доказательством.
Следует также отметить, что argv не будет определяться вне main(), в то время как __progname обычно определяется как глобальная переменная, которую вы можете использовать из вашей функции use() или даже до вызова main() (например, стандартные конструкторы GCC).
Для этого есть расширение GNU, так что вы можете получить доступ к имени вызова программы извне main(), не сохраняя его вручную. Однако было бы лучше сделать это вручную; что делает его переносимым, а не поддержкой расширения GNU. Тем не менее, здесь я приведу отрывок из имеющейся документации.
С the on-line GNU C Library manual (доступ сегодня).
«Многие программы, которые не читают ввод с терминала предназначены для выхода, если любой системный вызов не По соглашению, сообщение об ошибке от такой программы должна начинаться с . название программы, Sans каталоги Вы можете найти это имя в переменной program_invocation_short_name
, полное имя файла хранится переменная program_invocation_name
Variable: обугленного * program_invocation_name . Значение этой переменной - это имя, которое использовалось для вызова программы, запущенной в текущем процессе. Это то же самое, что и
argv[0]
. Обратите внимание, что это необязательно является полезным именем файла; часто он не содержит имен каталогов.Variable: символ * program_invocation_short_name значение этой переменной является имя, которое используется для вызова программы, выполняемой в текущем процессе, с именами каталогов удалены. (То есть, это то же самое, как
program_invocation_name
минус все до последней косой черты, если таковые имеются.)
Библиотека код инициализации устанавливает обе из этих переменных перед вызовом основной.
Примечание по переносимости: Эти две переменные являются расширениями GNU. Если вы хотите, чтобы ваша программа работала с библиотеками, отличными от GNU, вы должны сохранить в главном файле значение argv[0]
, а затем сами удалить имена каталогов. Мы добавили эти расширения, чтобы можно было писать автономные подпрограммы отчетности об ошибках, которые не требуют явного сотрудничества с основными ».
__progname - просто argv [0], а примеры в других ответах здесь показывают слабые стороны использования его Хотя я и не переносился, я использую readlink on/proc/self/exe (Linux, Android) и читаю содержимое/proc/self/exefile (QNX).
- 1. Читать с argv [0]
- 2. (* ++ ARGV) [0], и в то время (с = * ++ ARGV [0])
- 3. Почему $ # ARGV 0?
- 4. Xcode ARGV [0] является именем пути вместо первого аргумента
- 5. Программа всегда возвращает 0 при ARGV [0]
- 6. Использование указателей перебирать ARGV []
- 7. Использование argv в C?
- 8. Настройка argv [0] в Haskell?
- 9. Perl, CMD, $ ARGV [0], медленно
- 10. Изменение argv [0] с winapi
- 11. DOCTEST == argv [0] как конвенция?
- 12. make getopt() process argv [0]
- 13. Как изменить argv [0] извне?
- 14. Почему разрешено изменять argv [0]?
- 15. Передача аргументов скрипту, получение: «Использование неинициализированного значения $ ARGV [0]»
- 16. Что такое эквивалент игры argv [0]?
- 17. Почему у нас есть argv [2] [0]
- 18. Изменение ARGV [0], когда exec'ing питон скрипт
- 19. $ ARGV [0] не работает в Solaris SPARC
- 20. Тщательно имитировать Argv [0] с bash
- 21. Возможно ли получить argv [0] в постскриптуме?
- 22. Отношение между PATH env и argv [0]
- 23. Может ли argv [0] содержать пустую строку?
- 24. COUT печатает «-0» вместо «0»
- 25. Интересные наблюдения argc, argv и его использование
- 26. Использование «argv» для передачи файлов изображений C++
- 27. Использование argv и strcmp в C
- 28. Как передать пользовательскую строку как argv [0] в программу
- 29. Perl переполняет все аргументы командной строки в $ ARGV [0]
- 30. Выражение SSRS - Если значение null, то вместо 0 вместо 0:
Рассмотрите: execl ("/ bin/sh "," hot potatoes "," -c "," echo $ 0 - Hi ", (char *) 0); Прекрасно работает, argv [0] -« горячий картофель », отгоняет« горячий картофель - Привет ». делать с именем исполняемого файла, который был запущен. – 2008-11-08 08:41:00
Несмотря на предыдущий комментарий, я согласен с тем, что argv [0] более портативен. И только несколько программ беспорядок с argv [0], как это, но любой злоумышленник может это сделать. Будьте осторожны с b принимая критические решения по argv [0]. – 2008-11-08 08:42:43