Jenkins控制台输出中的Echo off

81

我正在遵循指南,学习如何使用Jenkins签名Android apk。 我已经为Jenkins工作参数化了KSTOREPWD和KEYPWD。 Jenkins作业配置的一部分(Build->Execute shell)是将这些参数作为环境变量存储:

export KSTOREPWD=${KSTOREPWD}
export KEYPWD=${KEYPWD}
...
./gradlew assembleRelease
问题是当构建完成后,任何人都可以访问构建的“控制台输出”并查看输入的密码;其中部分内容如下:
08:06:57 + export KSTOREPWD=secretStorePwd
08:06:57 + KSTOREPWD=secretStorePwd
08:06:57 + export KEYPWD=secretPwd
08:06:57 + KEYPWD=secretPwd

我希望在export命令输出之前抑制回声,并在export命令之后重新启用回声。


在Superuser上有一个详细的答案:suppress-execution-trace-for-echo-command - TT--
3个回答

163

默认情况下,Jenkins使用执行Shell脚本命令并附加set -x。这会导致所有命令都被回显。

您可以在任何命令前键入set +x来临时覆盖此行为。当然,您需要set -x以重新开始显示它们。

您可以通过在构建步骤顶部放置以下内容来覆盖整个脚本的此行为:
#!/bin/bash +x


11
顺便提一下,我发现 #!/bin/bash 对我也起作用了。 - vikingsteve
有没有办法防止“临时”方法中打印set +x本身? - Leponzo

35

以下是一个如何以更安全的方式在Jenkinsfile中写入sh参数,避免输出的示例。此方法是根据官方文档建议进行改进的。主要魔法是set +x,如此答案所述。

单引号将使密钥作为环境变量被shell展开。双引号则可能不够安全,因为Groovy会插值密钥,导致常见操作系统进程列表(以及Blue Ocean和经典UI中的流水线步骤树)意外泄露它:

不安全,错误的用法:

node {
  withCredentials([string(credentialsId: 'mytoken', variable: 'TOKEN')]) {
    sh /* WRONG! */ """
      set +x
      curl -H 'Token: $TOKEN' https://some.api/
    """
  }
}

正确使用 ✅:

node {
  withCredentials([string(credentialsId: 'mytoken', variable: 'TOKEN')]) {
    sh '''
      set +x
      curl -H 'Token: $TOKEN' https://some.api/
    '''
  }
}

3
在你的shell中不需要使用'set +x'命令,withCredentials代码块会确保密码不会在控制台上打印出来,用'****'替换凭据的任何输出。 - jrodriguez
@jrodriguez 对于许多情况,它确实是这样。同时,这个答案也适用于其他情况,当它不是这样时。 :) - IvanRublev
Token 部分不需要用双引号吗? - ErikE

3
在您特定的情况下(使用gradle和jenkins),您还可以使用密码参数,使用{{link1:Gradle的环境变量模式}}(ORG_GRADLE_PROJECT_prop)。 Gradle将在您的项目上设置一个prop属性。
在您的情况下,它应该类似于这样。

enter image description here

你可以在gradle.properties中像这样使用它

signingConfigs {
    release {
        storeFile file(KEYSTORE)
        storePassword KSTOREPWD
        keyAlias ALIAS
        keyPassword KEYPWD
    }
}

顺便提一下 - 我建议使用凭据绑定插件来处理KEYSTORE 在此输入图片描述


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