在远程 SSH 服务器上运行本地 Shell 脚本,但该脚本需要另一个本地文件中的环境变量

在远程 SSH 服务器上运行本地 Shell 脚本,但该脚本需要另一个本地文件中的环境变量

我想在远程计算机上运行本地 bash 脚本来安装和设置 dokku 及其插件。 ( ssh root@remotehost 'bash -s' < dokku.sh) 该脚本需要一些配置值,例如AWS_BACKUP_ACCESS等。这些变量存储在单独的 json 文件中,如下所示:

/home/project/env.json

{
  "DB_NAME": "mydb",
  "APP_NAME": "web",
  "AWS_BACKUP_ACCESS": "xxx",
  "AWS_BACKUP_SECRET": "yyy",
}

多库

#!/bin/bash

json_file="/home/project/env.json"
# export all key values from env.json to globa env
for s in $(cat $json_file | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" ); do
    export $s;
done

wget https://raw.githubusercontent.com/dokku/dokku/v0.25.7/bootstrap.sh;
sudo DOKKU_TAG=v0.25.7 bash bootstrap.sh
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
dokku postgres:create "$DB_NAME"
dokku postgres:link "$DB_NAME" "$APP_NAME"
# use the Backup IAM profile
dokku postgres:backup-auth "$DB_NAME" "$AWS_BACKUP_ACCESS" "$AWS_BACKUP_SECRET" "$AWS_DEFAULT_REGION"

我的问题是,由于文件/home/project/env.json存储在本地,因此在远程服务器上运行脚本时如何使以下部分正常工作:

json_file="/home/project/env.json"
# export all key values from env.json to globa env
for s in $(cat $json_file | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" ); do
    export $s;
done

答案1

在本地读取 JSON 文件,然后建立 SSH 连接。另外,这将不再需要jq在远程系统上可用。

你的脚本:

#!/bin/sh

set -u -e

wget 'https://raw.githubusercontent.com/dokku/dokku/v0.25.7/bootstrap.sh'

sudo DOKKU_TAG=v0.25.7 bash bootstrap.sh
sudo dokku plugin:install 'https://github.com/dokku/dokku-postgres.git' postgres

dokku postgres:create "$DB_NAME"
dokku postgres:link "$DB_NAME" "$APP_NAME"

# use the Backup IAM profile
dokku postgres:backup-auth \
    "$DB_NAME" \
    "$AWS_BACKUP_ACCESS" \
    "$AWS_BACKUP_SECRET" \
    "$AWS_DEFAULT_REGION"

运行它:

ssh root@remotehost "env $( jq -r 'to_entries | map("\(.key)=\(.value)") | @sh' /home/project/env.json ) sh -s" <dokku.sh

这会env调用远程系统,并使用环境变量列表及其值作为参数。参数列表的末尾sh -s将读取您的dokku.sh脚本并执行它(该脚本不使用 bashism,因此无需调用更高级的 shell)。

我还在脚本中使用set -u它,使其在遇到未设置的变量时终止,并set -e在出现任何错误时终止。

显然,您可以将ssh-calling 位包装在本地脚本中,或者使用 Ansible 之类的东西来更可靠地完成整个事情。

答案2

最简单的方法是将scpenv.json 文件从本地计算机传输到远程,在脚本中使用它,然后将其删除。

或者,您可以编写一个脚本来设置/导出所需的变量,并scp在运行脚本之前将其导出到远程服务器。

事实上,许多涉及ssh引用、空格和变量的 PITA 问题可以通过scp将脚本和/或数据文件发送到远程服务器并运行该脚本来消除,而不是试图用一行代码来完成。具有多层嵌套引用。

sshd请注意,配置它是很常见的PermitUserEnvironment no(它通常被编译为 sshd 的默认设置之一),因此用户的环境不会从客户端计算机传递到 ssh 服务器。因此,在本地计算机上设置环境变量不太可能起作用。

相关内容