从Fastlane向shell脚本传递环境变量

7
我正在使用Fastlane(一种用于iOS的持续构建工具)来执行一个自定义的shell脚本,以解密一个文件。
这是该命令。
sh "./decrypt.sh ENV['ENCRYPTION_P12']"

我找不到一种方法将环境变量传递给该脚本。很明显,如果我在脚本中硬编码pwd,它可以正常工作。

sh "./decrypt.sh mypwd"

有什么建议吗?

顺便问一下,Fastlane配置是用哪种语言编写的?如果是Ruby,例如,将问题标记为Ruby将会吸引这里了解Ruby的人,而不是只知道shell的人,或者只知道Fastlane的人,你可能需要等待一段时间。 - Charles Duffy
从你的问题来看,你似乎是想将一个命令行参数传递给你的脚本,而不是一个环境变量。 - Dmitry Grigoryev
@DmitryGrigoryev,这也是我的第一个假设[请参见我的答案的编辑历史中的更长形式],但考虑到OP正在使用fastlane,我猜他们实际上已经有了一个环境变量,并且正在尝试确定如何将其作为参数。 - Charles Duffy
添加了 Ruby 标签。你能解释一下“踩”吗? - Lorenzo B
1
顺便说一句,我已经扩展了我的回答,深入探讨了以错误的方式(将变量替换为作为脚本传递给shell的代码)执行此操作的安全风险。 - Charles Duffy
显示剩余2条评论
2个回答

18

从当前的Shell中扩展

假设这里的 sh 是一个快车道命令,它会调用一个带有给定参数的shell命令作为脚本文本:

# as a fastlane directive
sh './decrypt.sh "$ENCRYPTION_P12"'
请注意,如果这个被字面上作为命令行来调用的话,需要一个-c参数:/bin/sh
# in other contexts
sh -c './decrypt.sh "$ENCRYPTION_P12"'
请注意,这绝对取决于ENCRYPTION_P12是一个环境变量 - 也就是说,由设置它的系统通过export导出到环境中。

从调用脚本中展开

话虽如此,如果它是一个环境变量,您有更好的选择:直接使用它。

也就是说,在decrypt.sh内部,您可以引用"$ENCRYPTION_P12"而无需显式设置它,因为shell将所有环境变量隐式导入为shell变量 - 并且它们会传递给子进程而不需要任何显式操作。


应避免的事情:Shell注入攻击

最后,顺带提一下:危险的做法可能是:

# INSECURE: DO NOT DO THIS
sh "./decrypt.sh #{ENV['ENCRYPTION_P12']}"
或者
# STILL INSECURE
sh "./decrypt.sh \"#{ENV['ENCRYPTION_P12'}\""
或者
# STILL INSECURE
sh "./decrypt.sh '#{ENV['ENCRYPTION_P12'}'"

这将把值代替在Ruby级别生成的字符串中。然而,这是危险的,因为该字符串被解析为代码--这意味着ENCRYPTION_P12的内容可能会被利用进行shell攻击。

例如,考虑以下bash语法的情况:

# this will make any of the above do Very Evil Things
ENCRYPTION_P12=$'$(rm -rf ~)\'$(rm -rf ~)\''

如果直接将其替换到生成的 shell 脚本中(而不是在参数扩展期间展开 '${foo}',这在已经经过此危险阶段的扩展阶段之后发生),则两个 rm 都将被执行。


非常感谢您的解释。在变量使用中,$符号和#符号有什么区别吗?请参见第一个代码片段和第三个代码片段。 - Lorenzo B
2
@LorenzoB.,有一个很大的区别:#{foo}在shell解析开始之前由Ruby评估,${foo}在大多数语法解析阶段完成后由shell评估。这就是为什么#{foo}会引入安全风险的原因:以这种方式替换的内容可能会被shell解析为代码。 - Charles Duffy
我正在尝试执行一个shell脚本,回到上一级目录。我还需要动态地传递一个参数给这个脚本,就像这样:lane :addPrivateKey do | options | sh ('cd .. && ./add_key.sh options[:clientKey]') end。现在它将options[:clientKey]作为参数而不是实际发送到lane的参数。我知道它是字符串,但如何从options变量中获取它? - nr5
如果您相信该值不会有恶意,请使用#{options[:clientKey]}。如果它包含空格或文字引号,则可能需要在其周围添加适当类型的引号。如果您无法保证该值是安全的,则可能需要编写Ruby代码将其导出为环境变量,以便通过该变量名称安全地访问它。 - Charles Duffy
能否反向操作,即从Fastlane环境向外部脚本发送一个值?我特别想在fastlane match完成后使配置文件ID可用于后续命令。 - Uche Ozoemena

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接