我目前正在编写一个 shell 脚本,用于构建 docker 镜像并重新启动在远程主机上运行的容器。下面是精简版的代码。
#!/bin/bash -xe
# usages: ./deploy.sh [PROJECT_REPO] [DOCKER_IMAGE] [TARGET_HOST] [KEYPAIR_PATH]
PROJECT_REPO=$1
DOCKER_IMAGE=$2
TARGET_HOST=$3
KEYPAIR_PATH=$4
PROJECT_DIR=$(echo $PROJECT_REPO | cut -d'/' -f 2 | cut -d '.' -f 1)
CONTAINER=$PROJECT_DIR
USER="ubuntu"
git clone $PROJECT_REPO
cd $PROJECT_DIR
if docker build -t $DOCKER_IMAGE .; then
docker push $DOCKER_IMAGE
if ssh -o StrictHostKeyChecking=no -i $KEYPAIR_PATH $USER@$TARGET_HOST -yes DOCKER_IMAGE=$DOCKER_IMAGE CONTAINER=$CONTAINER '\
docker pull $DOCKER_IMAGE && \
docker stop $CONTAINER
docker rm $CONTAINER
docker run -d --name=$CONTAINER $DOCKER_IMAGE'; then
echo "success"
else
echo "Failure"
exit 1
fi
else
echo "Error during building image"
exit 1
fi
我正在尝试使这个脚本通用化,以便可以通过运行带有项目详细信息(存储库URL、docker 镜像)的脚本将其用于不同的项目,但是当我尝试运行该脚本时,由于环境变量的值在远程主机上为空 DOCKER_IMAGE
, docker 命令出现错误。CONTAINER
答案1
对于这个简单的脚本,使用双引号而不是单引号将从父 shell 填充变量。
当然,如果你的脚本包含字符串或其他表达式,不是在您启动此脚本的主机上,父 shell 会插入这些内容,因此需要对其进行转义或以其他方式中和。但您这里似乎没有这些内容。
if ssh -o StrictHostKeyChecking=no -i $KEYPAIR_PATH $USER@$TARGET_HOST -yes "\
docker pull $DOCKER_IMAGE && \
docker stop $CONTAINER
docker rm $CONTAINER
docker run -d --name=$CONTAINER $DOCKER_IMAGE"; then
echo "success"
也许还可以考虑使用此处文档(这样您就可以在嵌入脚本中使用单引号和双引号),并了解何时引用内容。只要您的变量不包含不规则空格或通配符,这种方法就可以正常工作,但这很不可思议。