リモートSSHサーバーでローカルシェルスクリプトを実行しますが、スクリプトには他のローカルファイルの環境変数が必要です。

リモートSSHサーバーでローカルシェルスクリプトを実行しますが、スクリプトには他のローカルファイルの環境変数が必要です。

dokkuとそのプラグインをインストールして設定するために、リモートシステムでローカルbashスクリプトを実行したいと思います。 (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を使用しないため、より高いレベルのシェルを呼び出す必要はありません)。

set -uまた、設定されていない変数が見つかった場合は終了し、set -eエラーが発生した場合は終了するようにスクリプトでこれを使用しています。

明らかに、ssh呼び出しビットをローカルスクリプトにラップするか、Ansibleなどを使用してすべての操作をより確実に実行できます。

答え2

最も簡単な方法は、scpenv.jsonファイルをローカルシステムからリモートシステムに転送し、スクリプトで使用してから削除することです。

あるいは、スクリプトを作成して必要な変数を設定/エクスポートし、スクリプトをscp実行する前にリモートサーバーにエクスポートすることもできます。

実際に1行のコードを使用する代わりに、スクリプトおよび/またはデータファイルをリモートサーバーに送信してスクリプトを実行すると、引用符ssh、スペース、および変数に関連する多くのPITAの問題を排除できます。scpいくつかのレベルのネストされた参照があります。

sshdPermitUserEnvironment noユーザー環境がクライアントシステムからSSHサーバーに転送されないように設定するのが一般的です(通常はsshdのデフォルト設定の1つにコンパイルされます)。したがって、ローカルコンピュータで環境変数を設定することは機能しない可能性があります。

関連情報