Zsh导出忽略引号和反斜杠
我有一个 shell 脚本(我们称之为produce.sh),它以以下形式输出数据,但不将其保存到文件中:
FOO=value
BAR=value2
ZAP=value3
我想在 shell 脚本中使用这些值作为环境变量。我目前正在使用以下 shell 代码执行此操作:
export $(./produce.sh)
这很有效,除非右侧的值=包含空格。例如:
FOO=split value
我尝试了两种不同的方法produce.sh:
- 将值括在引号 (
FOO="split value") 中 - 使用反斜杠 (
FOO=split value)转义空格
这两个都不起作用:如果我检查环境变量,FOO包含"split在第一个示例和split第二个示例中。
我怎样才能export正确处理这个问题?
回答
的f在参数扩展标志zsh将分裂上换行符的输入,所以这应该处理与空白输入值:
export ${(f)"$(./produce.sh)"}
发生了什么
来自produce.sh的输出:
- 键值对。
- 每个 kv 对都在自己的线上。
- 键与值之间由
=. - 语法类似于 shell,但不完全是 shell 语法,因此,
- 值中允许使用空格和其他一些 shell 特有的字符。
替换部分:
produce.sh:生成键值输出,例如:N=V1nP=V 2n。$(...): 命令替换。它被替换为输出,减去尾随换行符:N=V1nP=V 2。"...":引号确保先前的结果被视为下一步的单个术语。${(f)...}:将单个术语扩展为多个标量值,由于(f)标志而在换行符处拆分。结果是有效的'N=V1' 'P=V 2'。export: 分配和导出每个参数,就像export 'N=V1' 'P=V 2'.
另外一个选项
下面的替换添加了一些其他神秘的 zsh-isms 来创建关联数组。这避免了向消费 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.