GetCommandLine linux *true* эквивалент

Аналогичный вопрос для Linux-эквивалента GetCommandLine и CommandLineToArgv

Можно ли получить командную строку raw в Linux? Файл /proc/self/cmdline уничтожен.

./a.out files="file 1","file 2" param="2"

отпечатки

./a.outfiles=file 1,file 2param=2

что хлам

Экранирование командной строки работает для всех аргументов, кроме первого.

./a.out files=\"fil 1\",\"fil 2\"\ param=\"2\"

отпечатки

./a.outfiles="fil1","fil2" param="2"

person user877329    schedule 26.12.2012    source источник
comment
Как насчет вывода пробела между аргументами   -  person Vovanium    schedule 26.12.2012
comment
кажется, что аргументы разделены 0-байтами, а кавычки удалены. cat /proc/self/cmdline | tr '\000' ' ' возвращает cat /proc/self/cmdline   -  person aragaer    schedule 26.12.2012
comment
И /proc/self/cmdline не содержит необработанной командной строки; он содержит точно такую ​​же информацию, как argv.   -  person Keith Thompson    schedule 26.12.2012
comment
Это одно из фундаментальных различий между Windows и UNIX. Ни один из подходов не является принципиально правильным или неправильным, у них обоих есть свои преимущества и недостатки.   -  person Harry Johnston    schedule 29.12.2012


Ответы (1)


Вы не можете этого сделать. Аргументы командной строки фактически передаются новому процессу в виде отдельных строк. См. исходный код ядра Linux: kernel_execve.

Обратите внимание, что kernel_execve(...) принимает const char *argv[], поэтому в Linux нет такой вещи, как командная строка с длинной строкой, — это уровень выше, который должен разделить аргументы на отдельные компоненты.

Редактировать: на самом деле системный вызов здесь:

системный вызов excve

Но утверждение выше по-прежнему применимо. Параметр для argv уже разделен к тому времени, когда ядро ​​получает его из C-библиотеки, вызывающей exec.

Ответственность за создание массива argv[] лежит на «стартере программы» (обычно оболочка, но не обязательно). Он будет выполнять «подстановку» (расширение имен файлов с подстановочными знаками до фактических файлов, которым они соответствуют) и удаление кавычек, замену переменных и так далее.

Я также хотел бы указать, что, хотя в библиотеке C есть несколько вариантов «exec», есть только один путь в ядро. Все варианты заканчиваются системным вызовом execve, на который я ссылался выше. Другие варианты просто потому, что вызывающая сторона может не захотеть разбивать аргументы на отдельные элементы, поэтому библиотека C «помогает», делая это за программиста. Аналогично для передачи массива среды в новую программу - если программисту не нужна конкретная среда, он может просто вызвать вариант, который автоматически принимает родительский процесс env.

person Mats Petersson    schedule 26.12.2012
comment
В частности, все кавычки и подстановки выполнялись оболочкой. Вы можете получить к нему доступ только в том случае, если оболочка сохранила оригинал где-то, к чему может получить доступ ребенок. И это будет специфично для оболочки. - person Ben Voigt; 26.12.2012
comment
Матс, я предлагаю добавить информацию из комментария @BenVoigt к вашему ответу (хотя программы, отличные от оболочек, также могут вызывать программы и могут создавать argv по-разному). - person Keith Thompson; 26.12.2012
comment
@Keith: родительский процесс не обязательно должен быть оболочкой, правда. Но тогда вообще нет никакой командной строки для обсуждения, только массив аргументов для exec. Связано: system() вызывает оболочку для обработки командной строки. - person Ben Voigt; 26.12.2012
comment
@BenVoigt: в оболочке есть командная строка; дело в том, что он не виден вызываемому процессу. - person Keith Thompson; 26.12.2012
comment
Немного обновил. Я просто надеюсь, что это стоит усилий... :) - person Mats Petersson; 26.12.2012
comment
@Keith: запущенный процесс не был виден стандартным образом. Я уверен, что мы могли бы выяснить, как написать оболочку, которая каким-то образом передает его (временный файл, помеченный как удаляемый при закрытии и использующий заранее согласованный файловый дескриптор). - person Ben Voigt; 26.12.2012
comment
Вывод: НЕТ ПРАКТИЧЕСКОГО И ПРОСТОГО способа получить такие данные для текущего процесса. - person Mats Petersson; 26.12.2012
comment
@Mats Petersson: Что, если оболочка просто поместит все после имени программы в первую строку? Кроме того, такое поведение фактически делает GetCommandLine в Wine несовместимым, так как расширение *. Программа Windows может ожидать этот символ. - person user877329; 19.01.2013
comment
@BenVoigt Или оболочка может просто установить переменную среды с именем SHELL_ORIGINAL_INVOCATION или что-то в этом роде. Но с чего бы это? Большинство программистов Linux не против командной строки, обрабатываемой оболочкой, поэтому в этом нет необходимости. - person Joker_vD; 24.05.2013