当我检查系统的环境时,将弹出许多环境变量。如何只搜索特定变量?
我正在读的书说:
有时,环境中的变量数量会变得非常大,以至于您只对一个变量感兴趣时就不想看到所有显示的值。在这种情况下,可以使用
echo
命令显示环境变量的当前值。
如何在Linux终端中执行此操作?
当我检查系统的环境时,将弹出许多环境变量。如何只搜索特定变量?
我正在读的书说:
有时,环境中的变量数量会变得非常大,以至于您只对一个变量感兴趣时就不想看到所有显示的值。在这种情况下,可以使用
echo
命令显示环境变量的当前值。
如何在Linux终端中执行此操作?
Answers:
只是:
echo "$VARIABLENAME"
例如对于环境变量$HOME
,使用:
echo "$HOME"
然后打印类似于以下内容的内容:
/home/username
编辑:根据StéphaneChazelas的评论,如果您使用printenv
而不是echo
:
printenv HOME
printenv VAR
将全部显示(至少对于GNU实现而言)。
通过执行:
printenv
您将看到所有环境变量。有关更多信息,您可以看一下:
printenv
variablename
将仅显示命名变量;例如,printenv HOME
将做与大致相同的事情echo "$HOME"
。
重要的是要了解每个进程都有自己的环境变量集。
当一个进程调用fork()
系统调用,第二个进程(子)等同于第一(父)创建(此副本包括环境,它位于只是堆上方(或下方,这取决于你如何看待栈:-)
-但在Unix / Linux操作系统堆栈增长下从高地址)。
通常,子进程随后将调用execve()
系统调用,该系统调用将丢弃其(虚拟)内存中的所有内容,并从指定的二进制文件中的代码和数据部分进行重构。
但是,在重建堆栈时,它将execve()
在调用main()
函数之前(按此顺序)先将传递到堆栈的环境和参数字符串复制到堆栈上(返回之后(到入口)的许多crt0
引导代码工作已完成。在二进制文件中指定的点))。execve()
execve()
C库中有一些用于系统调用的包装程序,它将传递当前环境(即,父环境的副本),而不是提供它的调用方(因此,实际上,孩子将继承父环境)-请参见environ(7)
。
尝试(以root用户身份)运行命令ps axeww | less
……这将为您显示所有进程的环境!一个有趣的过程是进程ID 1(即init
进程-内核在启动时创建的第一个进程)。
如果要查看特定进程的环境(并且知道它是进程ID),请尝试运行命令cat /proc/<PID>/environ
(替换<PID>
为进程ID)。
请注意,如果一个进程具有足够的特权,它可以重写其自己的堆栈,这可能使您很难知道其环境是什么-您将在ps输出中看到一些这样的守护进程。
但是最后,所有这些华夫饼都归结为上面@chaos所说的,如果您想查看shell进程中特定环境变量的当前值,只需使用(builtin)命令echo "$<NAME>"
(替换<NAME>
为您感兴趣的环境变量)……只要注意,同一变量在另一个过程中可能具有不同的值,或者根本不存在。
e
选项ps
和/proc/…/environ
特殊文件可能并非在所有系统上都存在。(2)AFAIK,每个 Unix进程都有特权重写其堆栈并修改其环境变量。(3)有关更多讨论,请参见环境变量属于谁?(在超级用户上)。
ps
,但是现在您已经强调了这一点,我不记得为什么认为。
如果必须设置很多变量:
( set -o posix ; set ) | sort >~/vars.before
设置好之后:
( set -o posix ; set ) | sort >~/vars.after
而不是显示已设置的内容:
comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'
这样,您很快就会发现自己,可以使用cnf文件中预定义的多组Shell var,将它们与tmux结合使用将使您成为Shell环境中的配置管理大师。
# ---------------------------------------------------------
# cat cnf/qto.dev.host-name.cnf
# [MainSection]
# postgres_db_name = dev_qto
# postgres_db_host = host-name
#
# call by: doParseCnfEnvVars cnf/qto.dev.host-name.cnf
# ---------------------------------------------------------
doParseCnfEnvVars(){
cnf_file=$1;shift 1;
test -z "$cnf_file" && echo " you should set the cnf_file !!!"
INI_SECTION=MainSection
( set -o posix ; set ) | sort >~/vars.before
eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
-e 's/#.*$//' \
-e 's/[[:space:]]*$//' \
-e 's/^[[:space:]]*//' \
-e "s/^\(.*\)=\([^\"']*\)$/export \1=\"\2\"/" \
< $cnf_file \
| sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^#].*\=.*/p;}"`
# and post-register for nice logging
( set -o posix ; set ) | sort >~/vars.after
echo "INFO added the following vars from section: [$INI_SECTION]"
comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'
}
echo
命令的选择很差,因为它可能会转换变量的内容。它将输出具有相同名称的shell参数的内容。例如1
,如果使用Bourne shell或env vars之类的容器,则不一定相同*
。而且,对于名称无效的外壳变量名称,您不能使用该方法。