【问题标题】:Unable to export env variable from script无法从脚本导出环境变量
【发布时间】:2020-07-20 19:12:17
【问题描述】:

我目前正在努力运行我试图从 Jenkins 触发的.sh 脚本。

Jenkins“执行 shell”部分,我正在连接到远程服务器(Jenkins 代理没有合适的操作系统来构建我需要的东西。) ,使用:

cp -r . /to/shared/drive/to/have/access/on/remote
ssh -t -t username@servername << EOF
    cd /to/shared/drive/to/have/access/on/remote
    source build.sh dev
    exit
EOF

build.sh 中,我正在导出R_LIBS 来为不同的R 版本构建一个包。

...
for path in "${!rVersionPaths[@]}"; do
    export R_LIBS="${path}"
    Rscript -e 'install.packages(c("someDependency", "someOtherDependency"), repos="http://cran.r-project.org");'
...

设置R_LIBS 在此处的功能应该类似于在install.packages(...) 中设置lib。由于某种原因,R_LIBS export 没有被接收。同样设置其他环境变量,如 http_proxy 将被忽略。这会导致网络外部的任何请求失败。

有什么特别的方法可以实现吗?

【问题讨论】:

  • 这是一个 bash 问题吗?如果是,请删除不相关的详细信息并提供minimal reproducible example。否则删除 bash 标签
  • 你的 shell 脚本的第一行是什么?是否使用与默认 shell 相同的 shell?虽然它不应该真的有所作为。还会建议您将env 放入您的shell 脚本中以确认
  • @TarunLalwani 第一行是#!/bin/bash
  • 打印路径时,我确实得到了正确的路径。此外,在安装包中设置 lib 时,它似乎也有效。但是,是的,从脚本中设置环境变量似乎不起作用
  • 另外,当手动触发脚本(不使用 Jenkins)时,一切似乎都运行得很好。 Soo...当我通过 SSH 从连身衣服务器运行脚本时,我会失去任何权利吗?

标签: r bash jenkins ssh


【解决方案1】:

也许用 env 传递这些变量,比如

env R_LIBS="${path}" Rscript -e 'install.packages(c("someDependency", .....

【讨论】:

    【解决方案2】:

    好吧,我无法对问题发表评论,因此将其发布为答案。

    我在从 Jenkins 调用远程 shell 脚本时遇到了类似的问题,问题是从 Jenkins 调用脚本时未加载 bash_profile 变量,但在本地它可以工作。在 ssh 连接中加载 bash 配置文件为我解决了这个问题。

    在 build.sh 中为 bash_profile 添加源代码

    . ~/.bash_profilesource ~/.bash_profile

    或者 在 ssh 连接中重新加载 bash_profile

    `ssh -t -t username@servername << EOF
       . ~/.bash_profile
       your commands here
       exit
    EOF
    

    【讨论】:

    • 最好把你关心的设置从你的.bash_profle文件中拉出来;这些文件是故意不被采购的,而您通过手动采购它们会使您的设置过于复杂。
    【解决方案3】:

    您可以像这样在同一命令行中设置该变量:

    R_LIBS="${path}" Rscript -e \
        'install.packages(c("someDependency", "someOtherDependency"), repos="http://cran.r-project.org");'
    

    可以通过这种方式附加更多变量。请注意,这只会为在它们之后调用的命令(及其子进程)设置这些环境变量。

    【讨论】:

      【解决方案4】:

      您说“R_LIBS export 不会被接听”。 问题 值是否未设置?或者它是否设置为其他值并且您正在尝试覆盖它?

      SSH 可能正在调用“/bin/sh -c”。根据Why does 'cd' command not work via SSH?的第二个答案,您可以简化SSH命令并在Bash中显式调用build.sh脚本:

      cp -r . /to/shared/drive/to/have/access/on/remote
      ssh -t -t username@servername "cd /to/shared/drive/to/have/access/on/remote && bash -f build.sh dev"
      

      这使得 SSH 调用更类似于在远程交互式 shell 中调用命令。 (您可以避免采购脚本和导出变量。)

      当可以使用本地环境变量覆盖作为任何命令的前缀时,您不需要export R_LIBSenv R_LIBS(同意 Luis 的回答):

      ...
      for path in "${!rVersionPaths[@]}"; do
          R_LIBS="${path}" Rscript -e 'install.packages(c("someDependency", "someOtherDependency"), repos="http://cran.r-project.org");'
      ...
      

      Rscript 可能对环境变量做了很多工作。您可以通过将Rscript 替换为env 命令来验证您是否正在设置R_LIBS 环境变量并观察输出:

      ...
      for path in "${!rVersionPaths[@]}"; do
          R_LIBS="${path}" env
      ...
      

      根据本手册“Initialization at Start of an R Session”,Rscript 在几个地方查找以加载“站点和用户文件”:

      • $R_PROFILE
      • $R_HOME/etc/Renviron
      • $R_HOME/etc/Renviron.site
      • $R_ENVIRON_USER
      • $R_PROFILE_USER
      • ./.Rprofile
      • $HOME/.Rprofile
      • ./.RData

      该手册的“示例”部分显示了这一点:

      ## Not run: 
      ## Example ~/.Renviron on Unix
      R_LIBS=~/R/library
      PAGER=/usr/local/bin/less
      

      如果您添加--vanilla 命令行选项来忽略所有这些文件,那么您可能会得到不同的结果并且知道站点/init/environ 文件中的某些内容正在影响您的R_LIBS!我不能自己运行这个系统。希望我们已经为您提供了一些需要调查的领域。

      【讨论】:

        【解决方案5】:

        您可能不想source build.sh,直接调用它(即删除source 命令)。

        通过source-ing 文件,您的脚本在 SSH shell(可能是sh)中执行,而不是通过bash,听起来像是您想要的。

        【讨论】:

          猜你喜欢
          • 2016-03-01
          • 2018-04-13
          • 1970-01-01
          • 2016-12-08
          • 1970-01-01
          • 2017-12-25
          • 2015-07-24
          • 2012-10-26
          • 1970-01-01
          相关资源
          最近更新 更多