Linux process environment variables

How to read environment variables of a process

You can read the initial environment of a process from /proc//environ .

If a process changes its environment, then in order to read the environment you must have the symbol table for the process and use the ptrace system call (for example by using gdb ) to read the environment from the global char **__environ variable. There isn’t any other way to get the value of any variable from a running Linux process.

That’s the answer. Now for some notes.

The above assumes that the process is POSIX compliant, meaning that the process manages its environment using a global variable char **__environ as specified in the Ref Spec.

The initial environment for a process is passed to the process in a fixed-length buffer on the process’s stack. (The usual mechanism that does this is linux//fs/exec.c:do_execve_common(. ) .) Since the size of the buffer is calculated to be no more than the size required for the initial environment, you can’t add new variables without erasing existing variables or smashing the stack. So, any reasonable scheme to allow changes in a process’s environment would use the heap, where memory in arbitrary sizes can be allocated and freed, which is exactly what GNU libc ( glibc ) does for you.

If the process uses glibc , then it is POSIX compliant, with __environ being declared in glibc//posix/environ.c Glibc initializes __environ with a pointer to memory that it malloc s from the process’s heap, then copies the initial environment from the stack into this heap area. Each time the process uses the setenv function, glibc does a realloc to adjust the size of the area that __environ points to to accommodate the new value or variable. (You can download the glibc source code with git clone git://sourceware.org/git/glibc.git glibc ). To really understand the mechanism you will also have to read the Hurd code in hurd//init/init.c:frob_kernel_process() (git clone git://git.sv.gnu.org/hurd/hurd.git hurd).

Now if the new process is only fork ed, without a subsequent exec overwriting the stack, then the argument and environment copying magic is done in linux//kernel/fork.c:do_fork(. ) , where the copy_process routine calls dup_task_struct that allocates the new process’s stack by calling alloc_thread_info_node , which calls setup_thread_stack ( linux//include/linux/sched.h ) for the new process using alloc_thread_info_node .

Finally, the POSIX __environ convention is a user-space convention. It has no connection with anything in the Linux kernel. You can write a userspace program without using glibc and without the __environ global and then manage the environment variables however you like. No one will arrest you for doing this but you will have to write your own environment management functions ( setenv / getenv ) and your own wrappers for sys_exec and it is likely that no one will be able to guess where you put the changes to your environment.

Читайте также:  List all users and groups in linux

Источник

Show the environment variables of a running process in Linux

A quick mental dump in case I forget it again next time. First, check your PID :

$ ps faux | grep 'your_process' 508 28818 0.0 0.3 44704 3584 ? Sl 10:10 0:00 \_ /path/to/your/script.sh 

Now, using that PID (in this case, 28818), check the environment variables in /proc/$PID/environ .

$ cat /proc/28818/environ TERM=linuxPATH=/sbin:/usr/sbin:/bin:/usr/binrunlevel=3RUNLEVEL=3SUPERVISOR_GROUP_NAME=xxxPWD=/path/to/your/homedirLANGSH_SOURCED=1LANG=en_US.UTF-8previous=NPREVLEVEL=N 

Now to get that output more readable, you can do two things. Either parse the null character ( \0 ) and replace them by new lines ( \n ) or use the strings tool that does this for you.

Let’s take the hard path first, to see what’s going on.

$ cat /proc/28818/environ | tr '\0' '\n' TERM=linux PATH=/sbin:/usr/sbin:/bin:/usr/bin runlevel=3 RUNLEVEL=3 SUPERVISOR_GROUP_NAME=xxx PWD=/path/to/your/homedir LANGSH_SOURCED=1 LANG=en_US.UTF-8 previous=N PREVLEVEL=N 

Alternatively, you can use strings directly on the file.

$ strings /proc/28818/environ TERM=linux PATH=/sbin:/usr/sbin:/bin:/usr/bin runlevel=3 RUNLEVEL=3 SUPERVISOR_GROUP_NAME=xxx PWD=/path/to/your/homedir LANGSH_SOURCED=1 LANG=en_US.UTF-8 previous=N PREVLEVEL=N 

You could also add the e modifier to ps to also show all environment variables. Personally, I find /proc easier to interpret, since it only shows the environment variables.

$ ps e -ww -p 28818 PID TTY STAT TIME COMMAND 28818 ? Sl 0:00 /path/to/your/script.sh TERM=linux PATH=/sbin:/usr/sbin:/bin:/usr/bin runlevel=3 RUNLEVEL=3 SUPERVISOR_GROUP_NAME=xxx PWD=/var/www/vhosts/worker.nucleus.be/cron-tasks LANGSH_SOURCED=1 LANG=en_US.UTF-8 previous=N 

If you’ve got other tricks, I’d love to hear about them!

Want to subscribe to the cron.weekly newsletter?

I write a weekly-ish newsletter on Linux, open source & webdevelopment called cron.weekly.

It features the latest news, guides & tutorials and new open source projects. You can sign up via email below.

No spam. Just some good, practical Linux & open source content.

Who dis? 🤔

Hi! I’m Mattias Geniar, an independent developer, Linux sysadmin & general problem solver. Looking for help? I’m available for hire as a consultant. Want to get in touch? Have a look at my contact page.

Источник

How to Get environment variables of running process in Linux

This post we will talking about one of the useful things which administrator often has to use. The topic is How To Get environment variables of running process Linux . Let’s first start with what is environment variable and then find out How To Check Environment Variables for a Running Process in different flavor of Unix system

Читайте также:  Просмотр всех установленных пакетов linux

What is environment Variable

An environment variable is a dynamic-named value that can affect the way running processes will behave on a computer.

They are part of the environment in which a process runs. For example, a running process can query the value of the TEMP environment variable to discover a suitable location to store temporary files, or the HOME or USERPROFILE variable to find the directory structure owned by the user running the process.

Unix
environment variable as accessed as $VARIABLE

environment variable as accessed as %VARIABLE%

Many times we need to find out what environment variable were set when the process was started. One use case would be finding out environment variable for the oracle database instance started from Oracle cluster ware.

You may want to know what TNS_ADMIN variable ,oracle instance process are using. If it is not set ,it will be using default location $ORACLE_HOME/network/admin. We can find the environment variable using the below command on various flavor of Unix system.You just need to use the command on pmon process -id of the database instance to get the information

How To get environment variables of running process Linux?

The above command will help us in troubleshooting various issues.Hope you this post on how to get environment variables of running process Linux ,Solaris and AIX

Источник

Current environmental variables of a process

This question relates to this answer. Is it possible to get the current (not initial) environmental variables of a process by making a child process and checking its initial environmental variables? The idea is that the initial environment of a child process is inherited from the current environment of the parent.

2 Answers 2

The environment is a list of strings passed along the execve system call, just like the list of arguments. Period. What the applications do with that list of strings it receives is up to the application.

Now, by convention, that list is generally used differently from the list of arguments. Programs generally remember the list of environment variables they receive and reuse the same when executing another command.

They’ve got C library functions to help them doing that: the environment is made available as a environ variable, and you can retrieve and modify that list (the copy of the list of environment variables it received) with getenv , setenv , putenv , and functions like execvp , execl , system , popen . use that environ variable when executing commands (call execve with the environ they’re keeping track of).

Now applications don’t have to use that API. They can use their own way to manage the list of environment variables. Shells for instance, map environment variables to shell variables and are likely not to use putenv/setenv libc functions. perl has its %ENV associative array and so on.

Читайте также:  Проверка запущенного скрипта linux

You can always use gdb to attach to a process and make it call system(«env > /tmp/some-file») (assuming they are dynamically linked to the libc), but you’ve got no guarantee that env will get the same environment than another command would get if the command you’re attaching to was executing it in its own way (think of shells for instance). (also note that system() starts a shell (to interpret the command line) and shells may alter their environment on start up (try for instance env -i sh -c env ).

$ sleep 100 & [1] 17098 $ gdb --pid=$! /bin/sleep [. ] (gdb) p environ[0] $1 = 0x7fffd722d227 "STY=7498.pts-0.hostname" (gdb) p environ[1] $2 = 0x7fffd722d245 "TERM=screen-bce" (gdb) call system("env > /tmp/some-file") $4 = 0 (gdb) detach Detaching from program: /bin/sleep, process 17098 (gdb) quit $ cat /tmp/some-file GNOME_KEYRING_PID=6850 SSH_AGENT_PID=6844 SHLVL=1 [. ] 

Источник

Finding out environment variables of the process on Linux

As you probably know, each process on Linux can define its own environment variables (which are by default inherited by child processes). Let’s create an example process and pass it two environment variables:

First, we’re creating a process that will sleep for 120 seconds, then we’re saving its process id (PID) in a variable named $PID . We can read the initial variables from the /proc/$PID/environ file:

b=2a=1SHELL=/bin/bashWINDOWID=16831489QT_ACCESSIBILITY=1COLORTERM=rxvt-xpm . 

Since entries are separated by the null byte character (‘\0’), the output is not very readable, so let’s try to fix that:

-z option tells sed that new lines are separated by the null byte character, instead of the usual newline character — exactly what we need here. That output is now more readable:

b=2 a=1 SHELL=/bin/bash WINDOWID=16831489 QT_ACCESSIBILITY=1 COLORTERM=rxvt-xpm . 

Note: use this only for display purposes, entries are separated by the null byte character for a good reason — it’s the only character that can’t be part of the value.

Alternatives

We’re using e option to tell ps to show the environment variables after the command, -p to specify the process id, and -ww for wide output (unlimited width). Example output (entries are separated by spaces):

 657114 pts/47 S 0:00 sleep 120 b=2 a=1 SHELL=/bin/bash WINDOWID=16831489 QT_ACCESSIBILITY=1 COLORTERM=rxvt-xpm . 

Updated values

As I mentioned earlier, /proc/$PID/environ contains only initial variables. If the process changes its environment, and you want to read updated variables, you’ll need to do something like this:

echo 'p (char *) getenv("a")' | gdb -q -p $PID 

Note: This is a snapshot of the wiki page from the BetterWays.dev wiki, you can find the latest, fully formatted version here: betterways.dev/finding-out-environment-variables-of-the-process-on-linux.

Источник

Оцените статью
Adblock
detector