원격 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스크립트를 실행하기 전에 원격 서버로 내보낼 수 있습니다.

실제로 한 줄의 코드를 사용하는 대신 스크립트 및/또는 데이터 파일을 원격 서버로 보내고 스크립트를 실행하면 ssh따옴표, 공백 및 변수와 관련된 많은 PITA 문제를 제거할 수 있습니다 . scp여러 수준의 중첩 참조가 있습니다.

sshdPermitUserEnvironment no사용자 환경이 클라이언트 시스템에서 SSH 서버로 전달되지 않도록 이를 구성하는 것이 일반적입니다 (일반적으로 sshd의 기본 설정 중 하나로 컴파일됩니다). 따라서 로컬 컴퓨터에서 환경 변수를 설정하는 것은 작동하지 않을 수 있습니다.

관련 정보