2009-02-06 4 views
9

В Perl мне нужно прочитать среду других процессов.Есть ли способ прочитать переменные среды других процессов с использованием Perl и в среде Linux или Solaris?

  • Сценарий работает с правами root .
  • Сценарий будет работает как в Linux, так и в Solaris.
  • Я бы хотел, чтобы решение было в основном не агностиком платформы, по крайней мере, между Linux и Solaris. В Linux проверка/env/< proc_id>/environ может дать мне ответ.
  • Хотелось бы избежать использования вилки. У меня уже есть решение forking «/ usr/ucb/ps-auxwwwe $ pid»

Любые идеи?

ответ

7

Для Solaris вы можете попробовать procfs module from CPAN. Даже если этот модуль все еще кажется, совсем молодым, эта цитата звучит надежду:

Brian Farrell послал очень полезный патч, который обрабатывает осмотра ARGV и окружающей среды процессов , отличных от процесса в данный момент.

Я предполагаю, что это, вероятно, только начальная среда (так же, как файл environ под linux), но это похоже на то, что вы хотите?

В противном случае, хотя я вижу, что вы говорите, что не хотите развиваться, простое решение, вероятно, должно было бы прокрутить ~ 20 строк C, чтобы создать небольшую программу, которая просто выплевывает среду на Solaris как точный эквивалент Linux environ файл. У меня есть что-то очень похожее на C уже. Если вам интересно, я могу опубликовать его.

EDIT (после чтения OpenSolaris pargs.c): буфер среды перераспределяется в Solaris при изменении среды, поэтому указатель psinfo может быть недействительным. Для пуленепробиваемого решения вам нужно выискивать _environ. Это, наверное, больше хлопот, чем вам нужно ... pargs -e <pid> может быть более приятным для UCB ps(1), если вы все-таки идете по маршруту разветвления.

+1

будет ясно: pargs -e - это путь (оберните это внутри системного вызова perl) – PaulS

12

В linux выглядит так: /proc/<pid>/environ psuedofiles содержит переменную окружения, переданную при создании процесса. Если у вас есть достаточное разрешение, вы можете прочитать их.

Они не отслеживают изменения в среде процессов после запуска.

Это говорит о том, что вам нужно будет отключить дамп памяти процессов, чтобы получить то, о чем вы просите.

Tricky.

+0

Хех. Похоже, я на самом деле не прочитал его вопрос. Сожалею. – dmckee

+0

Файловая система Solaris/proc (Solaris 10), похоже, не включает даже исходную среду. –

+0

@Jonathan, посмотрите файл/proc/pid/psinfo и посмотрите struct psinfo от . Поле pr_envp является исходной средой. –

5

Первое, что приходит мне на ум, - это использовать GDB для присоединения к рассматриваемому процессу , а затем попросить GDB получить окружение для вас. Вы можете сделать это с помощью команды «show environment» в оболочке GDB .

Похоже, что есть модуль Perl, который может сделать это за вас, Devel::GDB. У меня еще нет , но это похоже на простую задачу программирования на . Создайте объект Devel :: GDB, подключитесь к процессу, который вы хотите , проверите, отправьте команду «show environment», а затем проанализируйте Результаты.

Я должен сказать, хотя ... когда решение является таким сложным, вы, , вероятно, делаете что-то еще неправильно. Почему в любом случае вам нужна среда для случайного процесса?

+0

Зачем вам нужна среда для случайного процесса, во всяком случае? Это часть скрипта, который собирает информацию о процессах, запущенных в системе. Данные сохраняются для последующего анализа. –

+0

show environment показывает среду gdb, а не процесс, к которому он привязан. Из руководства gdb: «Распечатайте значение переменной среды varname, которое будет передано вашей программе при ее запуске». Другими словами, среда отображения полезна, если вы планируете запускать программу, но не полезно сообщать вам о среде программы, к которой вы подключаетесь. Исправьте меня, если я ошибаюсь, но мои тесты и чтение руководства предполагают, что этот ответ совершенно неверен. –

2

Если ps может это сделать, как вы говорите, тогда ваш ответ можно найти где-нибудь в исходном коде ps. Это позволит избежать нереста нового процесса.

8

В комплект поставки GNU 'binutils' входит утилита CLI под названием strings. См. http://www.gnu.org/software/binutils/ для получения дополнительной информации.

strings /proc/pid/environ - распечатывает хороший список переменных окружения, таких как env.

+1

Я также пришел к поиску ответа, не относящегося к Linux. '/ proc/$$/environ' - это нулевой список строк' KEY = value' (я узнал, спросив «xxd/proc/$$/environ», но он, вероятно, где-то зарегистрирован). Вы можете превратить его в нечто более читаемое с помощью стандартных инструментов POSIX. Просто используйте 'cat/proc/$$/environ | tr '\ 0' '\ n''. – alsuren

+0

@alsuren Спасибо. Это работает. И xxd, и использование tr для фиксации вывода весьма полезны. –

0

В Linux может быть достаточно, чтобы разрешить символическую ссылку /proc/[pid]/cwd, см. procfs(5).