9

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?

jac_no_k
  • 237
  • 3
  • 4
  • 7

6 Answers6

12

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.

dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
11

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.

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
sixerjman
  • 111
  • 1
  • 3
  • 1
    I also came here looking for a non-perl Linux-specific answer. `/proc/$$/environ` is a null-separated list of `KEY=value` strings (I found out by asking `xxd /proc/$$/environ` but it is probably documented somewhere). You can turn it into something more readable with only standard POSIX tools. Just use `cat /proc/$$/environ | tr '\0' '\n'`. – alsuren Jun 05 '13 at 14:21
  • @alsuren Thanks. That works. Both xxd and the use of tr to fix up the output are quite helpful. – Bruce Dawson Jun 18 '14 at 21:50
7

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.

Martin Carpenter
  • 5,893
  • 1
  • 28
  • 32
4

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?

jrockway
  • 42,082
  • 9
  • 61
  • 86
  • Quote: Why do you need the environment for a random process, anyway? This is part of a script that gathers information on processes running on the system. The data is saved to be analyzed later. – jac_no_k Feb 06 '09 at 04:49
  • show environment shows the environment of gdb, not the process it is attached to. From the gdb manual: "Print the value of environment variable varname to be given to your program when it starts." In other words, show environment is helpful if you are planning to launch a program, but it is not useful for telling you about the environment of a program that you attach to. Correct me if I am wrong, but my tests and reading of the manual suggest that this answer is completely incorrect. – Bruce Dawson Jun 18 '14 at 21:42
2

If ps can do it, like you say, then your answer can be found somewhere in the source code of ps. That would avoid the spawning of a new process.

Thomas
  • 174,939
  • 50
  • 355
  • 478
0

On Linux it may be enough to resolve the /proc/[pid]/cwd symlink, see procfs(5).

Jakub Klinkovský
  • 1,248
  • 1
  • 12
  • 33