Полная командная строка, когда она была напечатана

Я хочу получить полную командную строку по мере ее ввода.

Эта:

" ".join(sys.argv[:])

здесь не работает (удаляет двойные кавычки). Также я предпочитаю не возвращаться к чему-то, что было разобрано и расколото.

Есть идеи?

Заранее спасибо.

Ты опоздал. К тому времени, когда введенная команда попадет на Python, ваша оболочка уже поработала над своей магией. Например, кавычки потребляются (как вы заметили), переменные получают интерполяцию и т. Д.

В среде unix это вообще не возможно … на что вы можете надеяться – это командная строка, переданная вашему процессу.

Поскольку оболочка (по существу, любая оболочка) может несколько раз набить типизированную командную строку, прежде чем передать ее ОС на выполнение.

Как уже упоминалось, это, вероятно, невозможно сделать, по крайней мере, не надежно. В некоторых случаях вы можете найти файл истории для оболочки (например, «bash», но не «tcsh») и получить от этого пользовательский ввод. Я не знаю, сколько, если таковые имеются, контроля над средой пользователя.

* Никс

Посмотрите на исходный формат стека (Linux на i386), который обеспечивает доступ к командной строке и среде программы : процесс видит только отдельные аргументы.

Вы не можете получить командную строку, как она была напечатана в общем случае. В Unix оболочка анализирует командную строку на отдельные аргументы и в конечном итоге execv(path, argv) которая вызывает соответствующий syscall . sys.argv выводится из параметра argv переданного execve() . Вы можете получить что-то эквивалентное, используя " ".join(map(pipes.quote, argv)) хотя вам не нужно, например, если вы хотите перезапустить скрипт с немного отличающимися параметрами командной строки, тогда достаточно sys.argv ( во многих случаях ), см. Можно ли установить флаг python -O (optimize) внутри скрипта?

Существуют некоторые творческие (не практические) решения:

  • прикрепите оболочку с помощью gdb и допросите ее (большинство оболочек могут повторять одну и ту же команду дважды) – вы должны иметь возможность получить почти ту же команду, что и набрав, или прочитать ее файл истории напрямую, если он обновлен до выхода вашего процесса
  • использовать экран, утилиты сценария, чтобы получить сеанс терминала
  • используйте кейлоггер, чтобы получить то, что было напечатано.

Windows

В Windows собственный интерфейс CreateProcess() представляет собой строку, но python.exe по-прежнему получает аргументы в виде списка. subprocess.list2cmdline(sys.argv) может помочь обратить вспять процесс. list2cmdline предназначен для приложений, использующих те же правила, что и среда выполнения MS C – один из них – python.exe . list2cmdline не возвращает командную строку по мере ее ввода, но в этом случае возвращает функциональный эквивалент.

На Python 2 вам может понадобиться GetCommandLineW() , чтобы получить символы Unicode из командной строки, которые не могут быть представлены в кодировке Windows ANSI (например, cp1252).

Если вы работаете в Linux, я предлагаю обезьяну с командой ~ / .bash_history или командой history, хотя я считаю, что команда должна завершить выполнение до того, как она будет добавлена ​​в историю оболочки.

Я начал играть с:

 import popen2 x,y = popen2.popen4("tail ~/.bash_history") print x.readlines() 

но я получаю странное поведение, когда оболочка, похоже, полностью не сливается с файлом .bash_history

В linux есть /proc/<pid>/cmdline который находится в формате argv[] (т. Е. Между всеми линиями существует 0x00, и вы не можете действительно знать, сколько строк существует, так как вы не получаете argc , хотя вы будете знать это, когда в файле заканчиваются данные;).

Вы можете быть уверены, что эта командная строка уже запущена, так как выполняется все экранирование / переменная, и параметры являются красивыми пакетами (без лишних пробелов между параметрами и т. Д.).