【问题标题】:shell/bash while read export variable not working for subtitute [duplicate]读取导出变量时的shell / bash不适用于替代[重复]
【发布时间】:2021-12-06 14:22:21
【问题描述】:

我想从文件中导出变量。这是我的文件

cat file.txt
VERSION=1.0.0
LOCATION=USA
NAME=sample
ENVIRONMENT=$ENV

我使用这个 while 循环导出该文件上的所有变量

while read vars; do export $vars;done < file.txt

所有变量都已成功导出,ENVIRONMENT 除外 我得到了这个值,ENVIRONMENT=$ENV(预期值是ENVIRONMENT=staging)。

printenv | grep ^ENV
ENV=staging

我的问题是,为什么在使用 while loop 时它不起作用,但如果我们手动导出 (e.g export ENVIRONMENT=$ENV) 时它会起作用??

其实有很多方法,从文件中导出变量,例如我可以使用envsubst &lt; file &gt; file1,然后使用while loop,但我只需要解释上面的情况。

【问题讨论】:

  • 你为什么不直接使用source?还是. 以防sh?只需执行source file.txt,所有变量都将在您的环境中
  • 因为如果文件中有#,它将不起作用
  • 嗯? source 通过常规解析器运行,因此它可以很好地跳过 cmets。你是什​​么意思“如果文件中有# 将不起作用”?
  • 请注意,如果您想export 的东西,您需要在获取文件之前启用自动导出。 set -a; . file.txt; set +a 你来了。
  • @TarasKhalymon,警告:source file.txt 只是设置常规 shell 变量,而不是环境变量,除非 file.txt 包含 export 指令或 set -a 已启用。

标签: linux bash shell sh


【解决方案1】:

展开顺序为described in POSIX:

扩词顺序如下:

  1. 应从头到尾执行波浪号扩展(请参阅波浪号扩展)、参数扩展(请参阅参数扩展)、命令替换(请参阅命令替换)和算术扩展(请参阅算术扩展)。参见令牌识别中的第 5 项。

  2. 除非 IFS 为空,否则应对步骤 1 生成的字段部分执行字段拆分(请参阅字段拆分)。

  3. 应该执行路径名扩展(参见路径名扩展),除非 set -f 生效。

  4. 应始终最后执行报价删除(请参阅报价删除)。

对于参数扩展,tl;dr 是:

${参数}

参数的值,如果有的话,应该被替换。

您会注意到定义不是递归的或多遍的。没有“5.返回步骤1并重复,直到无法进行进一步的扩展”,或“应替换参数的值(如果有),并重复该过程,直到找不到更多的参数扩展。”

这意味着export $vars 将在第 1 步中扩展 $vars,但不会重复该步骤,因此不理会$ENV

这也是所有其他编程语言的基本工作方式,例如爪哇:

String foo="bar";
String bar="baz";
// Prints `bar` without recursively resolving it into `baz`
System.out.println(foo);  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-16
    • 2016-05-10
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 2021-02-15
    • 2020-09-25
    相关资源
    最近更新 更多