Shell Zsh导出忽略引号和反斜杠

Shell Zsh导出忽略引号和反斜杠,shell,environment-variables,zsh,Shell,Environment Variables,Zsh,我有一个shell脚本(我们称之为product.sh),它以以下形式输出数据,但不将其保存到文件中: FOO=value BAR=value2 ZAP=value3 我想在shell脚本中将这些值用作环境变量。我目前正在使用以下shell代码执行此操作: export $(./produce.sh) 这非常有效,除非=右侧的值包含空格。例如: FOO=split value 我在product.sh中尝试了两种不同的方法: 将值括在引号中(FOO=“拆分值”) 用反斜杠转义空格(FOO=

我有一个shell脚本(我们称之为
product.sh
),它以以下形式输出数据,但不将其保存到文件中:

FOO=value
BAR=value2
ZAP=value3
我想在shell脚本中将这些值用作环境变量。我目前正在使用以下shell代码执行此操作:

export $(./produce.sh)
这非常有效,除非
=
右侧的值包含空格。例如:

FOO=split value
我在
product.sh中尝试了两种不同的方法:

  • 将值括在引号中(
    FOO=“拆分值”
  • 用反斜杠转义空格(
    FOO=split\value
  • 这两个都不起作用:如果我检查环境变量,
    FOO
    在第一个示例中包含
    “split
    ,在第二个示例中包含
    split\


    如何获得导出以正确处理此问题?

    zsh
    中的
    f
    参数扩展标志将在换行符上拆分输入,因此应使用空格处理输入值:

    export ${(f)"$(./produce.sh)"}
    

    发生了什么事 product.sh的输出:

    • 键值对
    • 每对kv线路都有自己的线路
    • 键与值之间用
      =
      分隔
    • 语法类似于shell,但不完全是shell语法
    • 值中允许使用空格和shell特有的一些其他字符
    替换部分:

    • product.sh
      :生成键值输出,例如:
      N=V1\nP=v2\N
    • $(…)
      :命令替换。它被替换为输出,减去尾随的换行:
      N=V1\nP=v2
    • “…”
      :引号确保先前的结果被视为下一步的单个术语
    • ${(f)…}
      :将单个项扩展为多个标量值,由于
      (f)
      标志,在换行符上拆分。结果实际上是
      'N=V1''P=v2'
    • export
      :分配和导出每个参数,就像
      export'N=V1''P=v2'

    另一种选择 下面的替换添加了一些其他神秘的zsh ISM来创建关联数组。这避免了向消费shell的 环境:

    % ./s2.sh
    A=A
    B=
    C=C C
    % typeset -A vals=("${(@s:=:)${(f)"$(./s2.sh)"}}")
    % print ${vals[A]}
    A
    % print ${vals[C]}
    C C
    
    一个小的折衷-如果值包含一个等于,这将不起作用,例如。
    D=D=D

    zsh
    中的
    f
    参数扩展标志将在换行符上拆分输入,因此应使用空格处理输入值:

    export ${(f)"$(./produce.sh)"}
    
    FOO=split value
    

    发生了什么事 product.sh的输出:

    • 键值对
    • 每对kv线路都有自己的线路
    • 键与值之间用
      =
      分隔
    • 语法类似于shell,但不完全是shell语法
    • 值中允许使用空格和shell特有的一些其他字符
    替换部分:

    • product.sh
      :生成键值输出,例如:
      N=V1\nP=v2\N
    • $(…)
      :命令替换。它被替换为输出,减去尾随的换行:
      N=V1\nP=v2
    • “…”
      :引号确保先前的结果被视为下一步的单个术语
    • ${(f)…}
      :将单个项扩展为多个标量值,由于
      (f)
      标志,在换行符上拆分。结果实际上是
      'N=V1''P=v2'
    • export
      :分配和导出每个参数,就像
      export'N=V1''P=v2'

    另一种选择 下面的替换添加了一些其他神秘的zsh ISM来创建关联数组。这避免了向消费shell的 环境:

    % ./s2.sh
    A=A
    B=
    C=C C
    % typeset -A vals=("${(@s:=:)${(f)"$(./s2.sh)"}}")
    % print ${vals[A]}
    A
    % print ${vals[C]}
    C C
    
    一个小的折衷-如果值包含一个等于,这将不起作用,例如。
    D=D=D

    FOO=split value
    
    不将变量设置为包含空格的值。它临时将
    FOO
    设置为拆分,并在设置了
    FOO
    的环境中运行命令
    value
    。总体效果与

    (export FOO=split; value)
    
    你可以通过做一个

    FOO=split printenv
    
    它将运行
    printenv
    ,并在其输出中显示
    FOO
    的值


    要将变量设置为包含空格的值,需要转义空格,例如使用

    FOO=split\ value
    
    或者使用引号

    要处理此文件,可以使用
    eval

    eval export $(./produce.sh)
    
    当然,只有当您完全控制product.sh向stdout写入的内容(即不要让任何受污染的数据潜入)时,才应该这样做,因为
    eval
    是一个潜在的安全漏洞

    或者,您可以修改product.sh以在每行前面已经生成
    export
    前缀,然后只进行一次修改

    eval $(./produce.sh)
    
    不将变量设置为包含空格的值。它临时将
    FOO
    设置为拆分,并在设置了
    FOO
    的环境中运行命令
    value
    。总体效果与

    (export FOO=split; value)
    
    你可以通过做一个

    FOO=split printenv
    
    它将运行
    printenv
    ,并在其输出中显示
    FOO
    的值


    要将变量设置为包含空格的值,需要转义空格,例如使用

    FOO=split\ value
    
    或者使用引号

    要处理此文件,可以使用
    eval

    eval export $(./produce.sh)
    
    当然,只有当您完全控制product.sh向stdout写入的内容(即不要让任何受污染的数据潜入)时,才应该这样做,因为
    eval
    是一个潜在的安全漏洞

    或者,您可以修改product.sh以在每行前面已经生成
    export
    前缀,然后只进行一次修改

    eval $(./produce.sh)
    

    要将变量设置为包含空格的值,您需要对空格进行转义,例如“这正是我在问卷中描述的操作”