Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to read environment variables of other processes using Perl and in a Linux or Solaris environment?

In Perl, I need to read the environment of other processes.

  • The script is running with root privileges.
  • The script will be running in both Linux and Solaris.
  • I would like a solution that's mostly platform agnostic, at least between Linux and Solaris. In Linux, examining the /env/<proc_id>/environ can get me the answer.
  • I would like to avoid having to fork. I already have a solution forking "/usr/ucb/ps -auxwwwe $pid"

Any ideas?

like image 931
jac_no_k Avatar asked Feb 06 '09 01:02

jac_no_k


4 Answers

In linux it looks like the /proc/<pid>/environ psuedofiles contain the environ variable passed when the process was created. If you have sufficient permission, you can read those.

They do not appear to track changes in the processes environment after launch.

That suggests that you would have to disect the processes memory dump to get what you're asking for.

Tricky.

like image 188
dmckee --- ex-moderator kitten Avatar answered Nov 13 '22 07:11

dmckee --- ex-moderator kitten


The GNU 'binutils' package includes a CLI utility called strings. See http://www.gnu.org/software/binutils/ for more info.

strings /proc/pid/environ - prints out a nice list of the environment variables much like env.

like image 41
sixerjman Avatar answered Nov 13 '22 07:11

sixerjman


For Solaris, you could try the procfs module from CPAN. Even though this module still seems quite young, this quote sounds hopeful:

Brian Farrell sent a very useful patch which handles inspection of argv and environment of processes other than the currently running process.

I imagine that this is probably just the initial environment (just like the environ file under linux), but that seems to be what you want?

Otherwise, although I see you say you don't want to fork, a simple solution would probably to crank ~20 lines of C to produce a small program that just spits out the environment on Solaris as the exact equivalent of the Linux environ file. I have something very similar in C already. If you're interested, I can post it.

EDIT (after reading OpenSolaris pargs.c): The environment buffer is reallocated under Solaris when the environment changes, so the psinfo pointer may be invalid. For a bullet proof solution, you need to hunt down _environ. That's all probably more hassle than you need... pargs -e <pid> might be a nicer alterative to UCB ps(1) if you do go the fork route, though.

like image 7
Martin Carpenter Avatar answered Nov 13 '22 06:11

Martin Carpenter


The first thing that comes to my mind is using GDB to attach to the process in question, and then asking GDB to get the environment for you. You can do this with the "show environment" command in the GDB shell.

It looks like there is a Perl module that can do this for you, Devel::GDB. I have not tried it yet, but it looks like a Simple Matter Of Programming to create the Devel::GDB object, connect to the process you want to inspect, send the "show environment" command, and then parse the results.

I do have to say though... when the solution is this complicated, you are probably doing something else wrong. Why do you need the environment for a random process, anyway?

like image 4
jrockway Avatar answered Nov 13 '22 06:11

jrockway