在Linux环境下(我的情况是XUbuntu),是否有一种方法可以找出从控制台运行的命令访问了哪些环境变量?必须有一种方法可以找到这些变量,因为有人必须向程序提供值。但是是否有默认方法来执行此操作?在这里所说的程序是xprintidle。
您是指实际访问还是进程的定义环境变量?
对于定义的环境变量,您可以使用:
perl -pe 's,\00,\n,g' /proc/xxxx/environ
这里的xxxx
是您的进程PID。
对于已访问的变量,您需要使用类似ltrace
的工具,并检查是否存在getenv()
调用。
getenv()
! - fgegetenv
访问环境,因此跟踪它通常(但并非总是)有帮助。请参见我的答案。一些程序可以使用environ
或main
的第三个参数获取环境变量。实际上很少有程序这样做! - Basile Starynkevitchgetenv
?如果你打算 fork
并且不想干扰环境数组,那么肯定会调用 setenv
,但是 getenv
呢? - Šimon Tóthputenv
,而不是getenv
!getenv
在许多程序中都很常用,例如ls
- 可以看 http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c 等等- 它用于 QUOTING_STYLE
、COLUMNS
、LS_BLOCK_SIZE
、环境变量等。 - Basile Starynkevitch您可以使用printenv
命令查看传递给程序的环境变量。
程序查看其环境的一种方式是使用getenv
调用,因此您可以使用跟踪程序或LD_PRELOAD
技巧来包装该调用并找出它们正在寻找什么。
但是,并非所有程序都使用getenv
来查看其环境。如果程序使用以下(不常见)格式的主函数,则可以通过envp
指针查看环境变量:
int main(int argc, char *argv[], char *envp[]) {
/* ... */
}
此外,程序可以通过environ
变量访问环境。
您可能会通过跟踪getenv调用来获得成功,但这并不是保证——它因程序而异。
env
命令来完成。
execve()
是程序执行的唯一方式(execl()
和其他函数只是它的包装器),它的第三个参数是一个指向所有环境变量的指针数组。你会在每个执行程序的 strace 中看到这个调用。 - fgegetenv
进行ltrace
会起作用,但是请注意,如果您正在尝试跟踪基于C的编程语言中的库调用,则需要小心。在Python 2.7和Perl 5.8.5中打印环境变量$USER
不会执行getenv
。尝试ltrace -o log -f perl -e 'print $ENV{"USER"};' > & /dev/null && grep getenv log | egrep '\bUSER\b'
或者ltrace -o log -f python -c 'import os;print os.environ["USER"]' > & /dev/null && grep getenv log | egrep '\bUSER\b'
。 - Ross Rogers