如何在sh脚本中传递目标参数以运行特定环境的Docker build

如何在sh脚本中传递目标参数以运行特定环境的Docker build,docker,sh,Docker,Sh,我正在构建一个sh脚本,以便能够一次性运行Docker容器。这样,我就不需要每次运行单个容器。 我现在需要添加的是一种运行docker compose up-build-target=环境将是DEV或PROD的方法。这样,我可以在docker设置中运行正确的环境 此时,我的脚本看起来如下所示,但当我尝试传递$2=$DEV时,它给了我一个错误[:=:预期的一元运算符,我不知道什么是正确的修复方法 #!/bin/bash CLEAN="clean" RUN="run&

我正在构建一个sh脚本,以便能够一次性运行Docker容器。这样,我就不需要每次运行单个容器。 我现在需要添加的是一种运行docker compose up-build-target=环境将是DEV或PROD的方法。这样,我可以在docker设置中运行正确的环境

此时,我的脚本看起来如下所示,但当我尝试传递$2=$DEV时,它给了我一个错误[:=:预期的一元运算符,我不知道什么是正确的修复方法

#!/bin/bash

CLEAN="clean"
RUN="run"
STOP="stop"
DEV="dev"
PROD="prod"

if [ "$#" -eq 0 ] || [ $1 = "-h" ] || [ $1 = "--help" ]; then
    echo "Usage: ./myapp [OPTIONS] COMMAND [arg...]"
    echo "       ./myapp [ -h | --help ]"
    echo ""
    echo "Options:"
    echo "  -h, --help    Prints usage."
    echo ""
    echo "Commands:"
    echo "  $CLEAN      - Stop and Remove containers."
    echo "  $RUN        - Build and Run containers."
    echo "  $STOP       - Stop containers."
    exit
fi

clean() {
    stop_existing
    remove_stopped_containers
    remove_unused_volumes
}

run() {
    echo "Cleaning..."
    clean

    echo "Running docker..."
        if [ $2 = $DEV ]; then
            echo "$DEV - Running in - $DEV - environment"
            docker-compose up --build -target=$DEV
        fi

}

stop_existing() {
    MYAPP="$(docker ps --all --quiet --filter=name=wetaxitask_api_dev)"
    REDIS="$(docker ps --all --quiet --filter=name=wetaxitask_redis)"
    MONGO="$(docker ps --all --quiet --filter=name=wetaxitask_mongodb)"

    if [ -n "$MYAPP" ]; then
        docker stop $MYAPP
    fi

    if [ -n "$REDIS" ]; then
        docker stop $REDIS
    fi

    if [ -n "$MONGO" ]; then
        docker stop $MONGO
    fi
}

remove_stopped_containers() {
    CONTAINERS="$(docker ps -a -f status=exited -q)"
    if [ ${#CONTAINERS} -gt 0 ]; then
        echo "Removing all stopped containers."
        docker rm $CONTAINERS
    else
        echo "There are no stopped containers to be removed."
    fi
}

remove_unused_volumes() {
    CONTAINERS="$(docker volume ls -qf dangling=true)"
    if [ ${#CONTAINERS} -gt 0 ]; then
        echo "Removing all unused volumes."
        docker volume rm $CONTAINERS
    else
        echo "There are no unused volumes to be removed."
    fi
}

if [ $1 = $CLEAN ]; then
    echo "Cleaning..."
    clean
    exit
fi

if [ $1 = $RUN ]; then
    run
    exit
fi

if [ $1 = $STOP ]; then
    stop_existing
    exit
fi
我想要实现的是,可以按照以下方式运行我的sh

./script.sh run dev or prod
  

调用shell函数时,它有自己的参数列表。指示:

在执行复合命令期间,命令的操作数临时应成为位置参数

因此,如果您定义并调用一个shell函数

打印两件东西{ 一美元是一美元 二美元等于二美元 } 打印两件东西foo bar 打印两件东西 $1和$2是函数的参数,而不是脚本

在脚本中,run函数中有两个错误

跑{ 如果[$2=$DEV];则:;fi } 这里,同样,$2是函数的第二个参数,而不是脚本;因为您调用它时只需在没有参数的情况下运行,所以它是一个空字符串。其次,您不引用这些变量中的任何一个,所以空字符串会被删除。这将扩展到无意义的[=dev],从而产生您看到的错误

您需要在顶层捕获变量中的位置参数,或者将其传递给shell函数。后一种方法的示例可能是:

跑{ 环境=$1此函数的第一个参数_ 清洁的 如果[$environment=$DEV];则:;fi } 在顶层;脚本的参数_ 如果[$1=$RUN];则 2美元 出口0 fi
在Docker上下文中,您可能会发现将其作为环境变量传递比较容易。使用Docker run-e选项或类似设置设置的任何内容都可以直接作为shell脚本中的环境变量使用。如果可能,在dev、test和prod中运行相同的映像通常也是最佳做法

-target nor-target似乎不是一个受支持的选项。在编写shell脚本时,强烈建议使用静态分析工具(也可以作为一种工具)来过滤脚本,有时会发现一些细微的错误。特别是,它会引起以下注意:第86行:运行→ SC2119:使用run$@if函数的$1应该表示脚本的$1。两种情况:1.您希望在生成时传递一个环境变量;或2.在容器运行时重写一个环境变量。我想您可能对1感兴趣。→ 在这种情况下,您应该在Dockerfile中使用,如果您确实对在构建时传递环境变量感兴趣,您是否认为您的问题与SO问题重复:当$1为空或未定义时,您实际上正在运行[=-help],这是一个语法错误。修复很简单;添加引号。如果[$1=-help]在dev中,我必须运行Nodemon,因为我在NodeJS中,这样,我就可以实时重新加载代码更改。不幸的是,我无法理解如何在这个示例中运行该脚本,该示例最后运行并退出脚本,而没有实际运行我的容器,并且忽略了我的env