如何显示环境变量的当前值?


24

当我检查系统的环境时,将弹出许多环境变量。如何只搜索特定变量?

我正在读的书说:

有时,环境中的变量数量会变得非常大,以至于您只对一个变量感兴趣时就不想看到所有显示的值。在这种情况下,可以使用echo命令显示环境变量的当前值。

如何在Linux终端中执行此操作?

Answers:


25

只是:

echo "$VARIABLENAME"

例如对于环境变量$HOME,使用:

echo "$HOME"

然后打印类似于以下内容的内容:

/home/username

编辑:根据StéphaneChazelas评论,如果您使用printenv而不是echo

printenv HOME

4
您忘记了引号(除非隐含zsh或rc / es语法)。echo命令的选择很差,因为它可能会转换变量的内容。它将输出具有相同名称的shell参数的内容。例如1,如果使用Bourne shell或env vars之类的容器,则不一定相同*。而且,对于名称无效的外壳变量名称,您不能使用该方法。
斯特凡Chazelas

5
还要注意,如果有多个具有相同名称的环境条目(好的,这是一种病理情况),您将获得哪个取决于外壳程序(通常是第一个或最后一个)。printenv VAR将全部显示(至少对于GNU实现而言)。
斯特凡Chazelas


5

重要的是要了解每个进程都有自己的环境变量集。

当一个进程调用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>为您感兴趣的环境变量)……只要注意,同一变量在另一个过程中可能具有不同的值,或者根本不存在。


1
(1)请注意,的e选项ps/proc/…/environ特殊文件可能并非在所有系统上都存在。(2)AFAIK,每个 Unix进程都有特权重写其堆栈并修改其环境变量。(3)有关更多讨论,请参见环境变量属于谁?(在超级用户上)。
G-Man说'恢复莫妮卡'

我想到某些系统可以防止非特权进程“隐藏”其命令行参数和环境(例如,从根目录运行)ps,但是现在您已经强调了这一点,我不记得为什么认为。
Murray Jensen

@MurrayJensen根据对我问过的“ curl”将其参数隐藏在ps中的高度投票的问题进行的讨论—在POSIX中未指定ps返回的是原先传递给该过程的args,还是该过程之后可能对其进行了修改的副本开始。某些系统(我认为Solaris ??)无论如何都会显示原始的args。 (这里是链接。) 这可能就是您所想的。:)
通配符

答对了!是的,Solaris当然可以“正确”执行此操作:-)感谢您的复习……
Murray Jensen

1

您可以通过以下方式获得想要的东西export

export | grep HOME

将显示$HOME变量的内容。


1

如果必须设置很多变量:

  ( 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 $_ "'
  }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.