How to pass arguments to Shell Script through docker run

后端 未结 7 1910
灰色年华
灰色年华 2020-11-30 17:49

I am new to the docker world. I have to invoke a shell script that takes command line arguments through a docker container. Ex: My shell script looks like:

#         


        
相关标签:
7条回答
  • 2020-11-30 18:07

    What I have is a script file that actually runs things. This scrip file might be relatively complicated. Let's call it "run_container". This script takes arguments from the command line:

    run_container p1 p2 p3
    

    A simple run_container might be:

    #!/bin/bash
    echo "argc = ${#*}"
    echo "argv = ${*}"
    

    What I want to do is, after "dockering" this I would like to be able to startup this container with the parameters on the docker command line like this:

    docker run image_name p1 p2 p3
    

    and have the run_container script be run with p1 p2 p3 as the parameters.

    This is my solution:

    Dockerfile:

    FROM docker.io/ubuntu
    ADD run_container /
    ENTRYPOINT ["/bin/bash", "-c", "/run_container \"$@\"", "--"]
    
    0 讨论(0)
  • 2020-11-30 18:09

    With Docker, the proper way to pass this sort of information is through environment variables.

    So with the same Dockerfile, change the script to

    #!/bin/bash
    echo $FOO
    

    After building, use the following docker command:

    docker run -e FOO="hello world!" test
    
    0 讨论(0)
  • 2020-11-30 18:16

    Use the same file.sh

    #!/bin/bash
    echo $1
    

    Build the image using the existing Dockerfile:

    docker build -t test .
    

    Run the image with arguments abc or xyz or something else.

    docker run -ti test /file.sh abc
    
    docker run -ti test /file.sh xyz
    
    0 讨论(0)
  • 2020-11-30 18:22

    Another option...

    To make this works

    docker run -d --rm $IMG_NAME "bash:command1&&command2&&command3"
    

    in dockerfile

    ENTRYPOINT ["/entrypoint.sh"]
    

    in entrypoint.sh

    #!/bin/sh
    
    entrypoint_params=$1
    printf "==>[entrypoint.sh] %s\n" "entry_point_param is $entrypoint_params"
    
    PARAM1=$(echo $entrypoint_params | cut -d':' -f1) # output is 1 must be 'bash' it     will be tested    
    PARAM2=$(echo $entrypoint_params | cut -d':' -f2) # the real command separated by     &&
    
    printf "==>[entrypoint.sh] %s\n" "PARAM1=$PARAM1"
    printf "==>[entrypoint.sh] %s\n" "PARAM2=$PARAM2"
    
    if [ "$PARAM1" = "bash" ];
    then
        printf "==>[entrypoint.sh] %s\n" "about to running $PARAM2 command"
        echo $PARAM2 | tr '&&' '\n' | while read cmd; do
            $cmd
        done    
    fi
    
    0 讨论(0)
  • 2020-11-30 18:25

    with this script in file.sh

    #!/bin/bash
    echo Your container args are: "$@"
    

    and this Dockerfile

    FROM ubuntu:14.04
    COPY ./file.sh /
    ENTRYPOINT ["/file.sh"]
    

    you should be able to:

    % docker build -t test .
    % docker run test hello world
    Your container args are: hello world
    
    0 讨论(0)
  • 2020-11-30 18:31

    There are a few things interacting here:

    1. docker run your_image arg1 arg2 will replace the value of CMD with arg1 arg2. That's a full replacement of the CMD, not appending more values to it. This is why you often see docker run some_image /bin/bash to run a bash shell in the container.

    2. When you have both an ENTRYPOINT and a CMD value defined, docker starts the container by concatenating the two and running that concatenated command. So if you define your entrypoint to be file.sh, you can now run the container with additional args that will be passed as args to file.sh.

    3. Entrypoints and Commands in docker have two syntaxes, a string syntax that will launch a shell, and a json syntax that will perform an exec. The shell is useful to handle things like IO redirection, chaining multiple commands together (with things like &&), variable substitution, etc. However, that shell gets in the way with signal handling (if you've ever seen a 10 second delay to stop a container, this is often the cause) and with concatenating an entrypoint and command together. If you define your entrypoint as a string, it would run /bin/sh -c "file.sh", which alone is fine. But if you have a command defined as a string too, you'll see something like /bin/sh -c "file.sh" /bin/sh -c "arg1 arg2" as the command being launched inside your container, not so good. See the table here for more on how these two options interact

    4. The shell -c option only takes a single argument. Everything after that would get passed as $1, $2, etc, to that single argument, but not into an embedded shell script unless you explicitly passed the args. I.e. /bin/sh -c "file.sh $1 $2" "arg1" "arg2" would work, but /bin/sh -c "file.sh" "arg1" "arg2" would not since file.sh would be called with no args.

    Putting that all together, the common design is:

    FROM ubuntu:14.04
    COPY ./file.sh /
    RUN chmod 755 /file.sh
    # Note the json syntax on this next line is strict, double quotes, and any syntax
    # error will result in a shell being used to run the line.
    ENTRYPOINT ["file.sh"]
    

    And you then run that with:

    docker run your_image arg1 arg2
    

    There's a fair bit more detail on this at:

    • https://docs.docker.com/engine/reference/run/#cmd-default-command-or-options
    • https://docs.docker.com/engine/reference/builder/#exec-form-entrypoint-example
    0 讨论(0)
提交回复
热议问题