我有一个 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
正确处理这个问题?
答案 0 :(得分:5)
f
中的 zsh
参数扩展标志将在换行符上拆分输入,因此这应该处理带有空格的输入值:
export ${(f)"$(./produce.sh)"}
produce.sh 的输出:
=
分隔。替换部分:
produce.sh
:生成键值输出,例如:N=V1\nP=V 2\n
。$(...)
:命令替换。它被替换为输出,减去尾随换行符:N=V1\nP=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
。
答案 1 :(得分:0)
FOO=split value
是否不将变量设置为包含空格的值。它临时将 FOO
设置为 split 并在已设置 value
的环境中运行命令 FOO
。整体效果类似
(export FOO=split; value)
您可以通过执行此操作进行实验
FOO=split printenv
将运行 printenv
并在其输出中显示 FOO
的值。
要将变量设置为包含空格的值,您需要对空格进行转义,例如使用
FOO=split\ value
或使用引号。
为了处理这个文件,你可以使用 eval
:
eval export $(./produce.sh)
当然,只有在您完全控制了 producer.sh 写入标准输出的内容时才应该这样做(即不要让任何受污染的数据潜入),因为 eval
是一个潜在的安全漏洞。>
或者,您可以修改produce.sh 以在每行前面生成export
前缀,然后只做一个
eval $(./produce.sh)