我有一个bash脚本,它在远程计算机的屏幕上运行另一个脚本,环境变量GITLAB_CI_TOKEN
在主机上设置,并且定义正确,但是远程计算机上的脚本configure.sh在执行时告知此环境变量为空,即使它与脚本定义在同一行上...
下面是我正在使用的命令:
ssh -o "StrictHostKeyChecking=accept-new" "${COMPUTERS_IPS[i]}" \
screen -S "deploy_${COMPUTERS_IPS[i]}" -dm " \
GITLAB_CI_TOKEN=${GITLAB_CI_TOKEN} \
bash \"${REMOTE_FOLDER}/configure.sh\" \"${REMOTE_FOLDER}\" > ${LOG_FILE} 2>&1;
"
此外,日志不会写入LOG_FILE,而是显示在屏幕的控制台上。过去两天我一直在为这件事抓狂......任何帮助或指导都将非常感谢:)
1条答案
按热度按时间1dkrff031#
为什么GITLAB_CI_TOKEN为“空”:
通过
ssh
向远程主机传递命令与通过eval
运行命令非常相似。例如,在您的示例中,第一次求值时转义的换行符在后续求值时变为 unescaped 换行符。考虑这个非常简单的程序,名为args
(将其放在bin或demo路径上的其他位置):这两种使用情形:
正如你所看到的,当我们通过
ssh
运行这个程序时,我们试图转义的换行符将我们的数据分割成两个单独的行,尽管我们试图将它们都放在一行中。这意味着你对GITLAB_CI_TOKEN的赋值只是一个常规的shell变量,而不是bash命令的作用域环境变量。作用域环境变量要求声明和命令发生在同一行中。最简单的方法可能是使用
export GITLAB_CI_TOKEN=${GITLAB_CI_TOKEN}
显式导出变量。出于类似的原因,命令的输出将显示在屏幕上,而不是日志文件中,因为
screen -dm "commands >output"
的外引号在第一次求值时被去掉,然后远程主机解析screen -dm commands >output
,并将输出重定向分配给screen
而不是commands
。是screen
程序将自己的输出写入日志文件。要向远程主机发送复杂的命令,您可能需要使用
printf %q
之类的工具,它可以生成转义输出,适合在类似eval
的上下文中进行安全评估。