AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 469543
Accepted
Tran Triet
Tran Triet
Asked: 2018-09-18 04:38:18 +0800 CST2018-09-18 04:38:18 +0800 CST 2018-09-18 04:38:18 +0800 CST

env 和 printenv 显示了哪些环境变量/shell 变量 [重复]

  • 772
这个问题在这里已经有了答案:
如果进程继承父环境,为什么我们需要导出? (5 个回答)
4年前关闭。

我已经看到了诸如此类的相关问题,但他们没有为我的问题提供确切的答案

从我的实验以及这个答案来看,printenv几乎env都显示了相同的系统变量集。

如果我将变量设置为

  1. /etc/bash.bashrc(应该是系统范围的系统变量)

    SYSTEM_ENVI=1000
    
  2. ~/.bashrc (应该是用户特定的系统变量)

    USER_ENVI=10
    

我什至注销并登录,因此 /etc/environment 生效。发生以下情况:

$echo $SYSTEM_ENVI
//outputs 1000
$echo $USER_ENVI
//outputs 10
$CURR_ENVI=1
$env | grep USER_ENVI
//nothing shows up, the same if I grepped SYSTEM_ENVI or CURR_ENVI
$set | grep USER_ENVI
//shows up USER_ENVI assignment, the same if I grepped SYSTEM_ENVI or CURR_ENVI

我的问题是:

  1. 什么系统变量做printenv/env打印?
  2. 应该使用set查看所有可访问变量(系统变量和局部变量)而不是printenvorenv吗?

关于不重复的理由

就我而言,这个问题和明显的答案帮助我认识到以下事实:

  1. Shell 变量不是环境变量
  2. /etc/bash.bashrc或~/.bashrc中的赋值不会创建环境变量,而是指示交互式非登录 shell 进程在启动时创建和初始化这些shell 变量。

我认为我的问题不一定与这个问题不同,但是阅读那个问题的标记答案并不像这篇文章中给出的答案那样让我满意。

environment-variables
  • 2 2 个回答
  • 4211 Views

2 个回答

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2018-09-18T04:49:28+08:002018-09-18T04:49:28+08:00

    env并printenv打印由执行它们的命令提供给它们的环境字符串列表(意味着包含环境变量定义)。调用者最终将执行以下操作:

    execve("/usr/bin/env", argv, envp);
    

    系统调用 whereargv和envp是两个字符串列表。

    env/printenv只打印 中的字符串列表envp,每行一个。

    按照惯例,其中的字符串envp采用 format var=value,但它们不一定是(我不知道有任何execve()实现它的实现),并且大多数env实现printenv并不关心它们何时显示它们。

    当调用者是 POSIX shell 时,它将包含在envp它传递给标记为导出env的 shell 变量列表中(因为用户在其上调用/ ,或者因为变量已经在 shell 的环境中)启动时收到)。exporttypeset -x

    如果 shell 在启动时收到的某些环境变量无法映射到 shell 变量,或者如果envp它收到的任何字符串不包含=字符,则取决于 shell 实现,这些字符串将被传递原封不动,否则外壳会剥去它们或其中的一些。

    例如bash,使用 GNUenv传递任意变量名称的列表(env虽然不能传递任意 envp 字符串,但它们必须包含 a =,并且使用的那些setenv()不能传递以=¹ 开头的一些)。

    $ env -i '=foo' '1=x' '+=y' bash -c printenv
    +=y
    1=x
    [...]
    

    (具有空名称的变量已删除,但其他变量未删除)。

    此外,如果 shell 接收envp到同一个变量名的多个字符串,取决于 shell,它们将全部传递,或者只传递第一个,或者只传递最后一个。

    setin POSIX shells 打印 shell 变量列表,包括支持数组/哈希类型的 shell 的非标量变量,无论它们是否已标记为导出。

    在 POSIX shell 中,您还可以使用export -p列出已标记为导出的变量。与env/相反printenv,它还列出了已标记为导出但尚未被赋予任何值的变量。

    在类似 Korn 的 shellksh中,如zsh或bash,您还可以使用typeset来获取更多信息,包括变量的属性,以及按类型列出变量(如typeset -a列出数组变量)。

    在这里,通过添加USER_ENVI=10您的~/.bashrc,您正在配置 shell 的交互式非登录调用,以在启动时bash定义一个USER_ENVI shell变量。由于您没有使用export,因此该变量仍然是一个 shell 变量(除非它在bash启动时位于环境中),因此它不会作为环境变量传递给该 shell 执行的命令。

    /etc/environment,本身,在 Ubuntu 16.04 上由pam_env.so可插入的身份验证模块读取。login像, sshd,等登录的应用程序lightdm将读取这些文件(如果配置为使用pam_env.so)/etc/pam.d并将相应的环境变量(此处与 shell 变量无关)传递给它们在您进行身份验证后以您的名字开头的命令(例如您的登录 shell 用于login/ sshd,或您的图形会话管理器lightdm...)。

    由于默认情况下会继承环境,因此当您的会话管理器执行终端仿真器进而执行您的登录 shell 时,这些环境变量将在每一步传递,您的 shell 会将它们映射到您可以在命令中扩展的 shell 变量符合之类的东西echo "$VAR"。

    pam_envenv 文件/etc/environment看起来像 shell 脚本,但pam_env不调用 shell 来解析它们,并且只理解 shell 语法的一个子集,并且只允许定义名称由一个或多个 ASCII 字母数字字符或下划线组成的变量(它确实让您定义一个123不是有效的 POSIX shell 变量名的变量)。


    ¹,要传递任意 env 字符串列表,您也可以execve()直接调用:

    perl -e 'require "syscall.ph";
             $cmd = "/bin/zsh";
             $args = pack("p*x[p]", "sh", "-c", "printenv");
             $env = pack("p*x[p]", "a=b", "a=c", "", "+=+", "=foo", "bar");
             syscall(SYS_execve(), $cmd, $args, $env)'
    

    在这里测试zsh而不是bash

    • 6
  2. user232326
    2018-09-18T12:21:06+08:002018-09-18T12:21:06+08:00

    通过做:

    USER_ENVI=10
    

    您正在设置一个变量,但不是一个环境变量。为此,您需要:

    export USER_ENVI=10
    

    或者

    USER_ENVI=10; export USER_ENVI
    

    这对您不起作用是合理的:

    $ env | grep SYSTEM_ENVI
    

    没有称为SYSTEM_ENVIset 的环境变量。/etc/environment由于您尚未发布其内容(似乎也没有使用它),因此我们无话可说。

    将打印的内容与应打印env的内容完全相同printenv(没有选项)。

    答案:

    1. 如果命令后没有选项或变量列表,则env 和printenv都将报告与实际设置的变量列表完全相同的列表。

    2. 您可以使用 set(不带选项)查看所有变量集。这并不意味着您必须使用它。这取决于您要列出的内容。仅列出环境变量列表是完全有效和正确的。

    • 1

相关问题

  • 设置组环境路径

  • 查找变量 $CDPATH 所在的路径?

  • 定义包含目录路径(对于 *.h) CentOS

  • $PAGER 可以包含空格吗?

  • 我可以在环境中手动设置多个代理吗?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve