2

I'm currently using the Bash command ps eww in order to get the environment variable of all processes.

For example, If I run the following command :

a=a b=b c=c sleep 1000

The output of ps eww | grep sleep would be:

23709 s007  S      0:00.00 sleep 1000 a=a b=b c=c TERM_PROGRAM=Apple_Terminal ...

In python, I've read about psutil package which has environ() method for extracting environment variables but it apply to current process or parent/child only (i.e. psutil.Process().environ() or psutil.Process().Parent().environ() etc..).

Perhaps there's a way to get the environment for every living process (according to name or any other attribute) ?

preferably, this option will comes on embedded package as part of python 2.7.1x

thanks

Zohar81
  • 4,554
  • 5
  • 29
  • 82
  • 1
    Keep in mind the `ps` command and the python `psutil` module can only report the env vars as they existed when the process was spawned. If the process modifies its env vars those changes will not be visible. Depending on why you want this info that may or may not be a problem. – Kurtis Rader Nov 21 '19 at 22:56
  • @KurtisRader, very good point. looks like the initial environment is treated like input arguments. any change wouldn't be reflected in the ps output. do you know the reason for that in macOS (or any other linux distribution)? – Zohar81 Nov 22 '19 at 10:33
  • It's because the original env vars are placed on the stack at a well defined offset before `main()` is called. In theory you could modify the value of existing env vars in place on the stack as long as the new value is no longer than the old value. But there isn't any way to delete or add new env vars on the stack -- those modifications require using the heap. And at that point utilities like `ps` have no way of knowing the virtual address of those vars. – Kurtis Rader Nov 23 '19 at 02:13

1 Answers1

3

The constructor of Process accepts the pid as an argument:

proc = psutil.Process(pid)
print(proc.name(), proc.environ())

Or you can iterate over all the processes with process_iter and filter them as you want:

for proc in psutil.process_iter():
    if proc.name() == 'sleep':
        print(proc.environ())
bereal
  • 32,519
  • 6
  • 58
  • 104
  • Thanks great thanks (I wasn't aware of `process_iter`). I've tried to use psutil out-of-the-box in macOS Mojave which comes with python 2.7.10, but it's nowhere to be found. can you recommend me a way to somehow embed this package in my script (although it's a different question) – Zohar81 Nov 21 '19 at 10:37
  • 1
    @Zohar81 I'd use [virtual env](https://docs.python.org/3/library/venv.html) or another sandbox like [pipenv](https://pipenv.kennethreitz.org/en/latest/) or [conda](https://docs.conda.io/en/latest/). You can then `pip install` anything you want inside it. – bereal Nov 21 '19 at 10:42