web-dev-qa-db-fra.com

Comment passer des arguments à Shell Script via l'exécution de docker

Je suis nouveau dans le monde des dockers. Je dois appeler un script Shell qui prend des arguments de ligne de commande via un conteneur docker. Ex: Mon script Shell ressemble à:

#!bin/bash
echo $1

Dockerfile ressemble à ceci:

FROM ubuntu:14.04
COPY ./file.sh /
CMD /bin/bash file.sh

Je ne suis pas sûr de savoir comment passer les arguments lors de l'exécution du conteneur

99
Akash Mehta

Utilisez le même file.sh

#!bin/bash
echo $1

Construisez l'image en utilisant le fichier Dockerfile existant:

docker build -t test .

Exécutez l'image avec les arguments abc ou xyz ou quelque chose d'autre.

docker run -ti test /file.sh abc

docker run -ti test /file.sh xyz
48
BMW

avec ce script dans file.sh

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

et ceci Dockerfile

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

tu devrais être capable de:

% docker build -t test .
% docker run test hello world
Your container args are: hello world
111
Partly Cloudy

Avec Docker, la bonne façon de transmettre ce type d’informations consiste à utiliser des variables d’environnement.

Donc, avec le même fichier Dockerfile, modifiez le script en

#!/bin/bash
echo $FOO

Après la construction, utilisez la commande suivante du menu fixe:

docker run -e FOO="hello world!" test
52
Michael

Il y a quelques choses qui interagissent ici:

  1. docker run your_image arg1 arg2 remplacera la valeur de CMD par arg1 arg2. C'est un remplacement complet du CMD, sans lui ajouter de valeurs. C'est pourquoi vous voyez souvent docker run some_image /bin/bash pour exécuter un shell bash dans le conteneur.

  2. Lorsque vous définissez à la fois une valeur ENTRYPOINT et une valeur CMD, docker démarre le conteneur en concaténant les deux et en exécutant cette commande. Ainsi, si vous définissez votre point d'entrée comme étant file.sh, vous pouvez maintenant exécuter le conteneur avec des arguments supplémentaires qui seront transmis comme arguments à file.sh.

  3. Entrypoints et Commands dans docker ont deux syntaxes, une syntaxe de chaîne qui lancera un shell et une syntaxe json qui effectuera un exec. Le shell est utile pour gérer des opérations telles que la redirection IO, la chaînage de plusieurs commandes (avec des éléments tels que &&), la substitution de variable, etc. vous avez déjà vu un délai de 10 secondes pour arrêter un conteneur (c’est souvent la cause) et concaténer un point d’entrée et une commande ensemble. Si vous définissez votre point d'entrée en tant que chaîne, il exécutera /bin/sh -c "file.sh", ce qui seul suffira. Mais si vous avez également une commande définie en tant que chaîne, vous verrez quelque chose comme /bin/sh -c "file.sh" /bin/sh -c "arg1 arg2" comme étant la commande lancée dans votre conteneur, ce qui n'est pas très bon. Voir le tableau ici pour plus d'informations sur l'interaction de ces deux options

  4. L'option Shell -c ne prend qu'un seul argument. Après cela, tout ce qui suit serait passé sous la forme $1, $2, etc., à cet argument unique, mais pas dans un script Shell intégré, à moins que vous n'ayez explicitement passé l'argument. C'est à dire. /bin/sh -c "file.sh $1 $2" "arg1" "arg2" fonctionnerait, mais /bin/sh -c "file.sh" "arg1" "arg2" ne fonctionnerait pas puisque file.sh serait appelé sans argument.

En résumé, la conception commune est la suivante:

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"]

Et vous exécutez ensuite cela avec:

docker run your_image arg1 arg2

Il y a un peu plus de détails à ce sujet à:

17
BMitch

Ce que j'ai est un fichier de script qui exécute des choses. Ce fichier de script peut être relativement compliqué. Appelons cela "run_container". Ce script prend des arguments depuis la ligne de commande:

run_container p1 p2 p3

Un run_container simple pourrait être:

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

Ce que je veux faire, c'est qu'après "docker" ceci, je voudrais pouvoir démarrer ce conteneur avec les paramètres sur la ligne de commande de docker comme ceci:

docker run image_name p1 p2 p3

et que le script run_container soit exécuté avec p1 p2 p3 en tant que paramètres.

Ceci est ma solution:

Dockerfile:

FROM docker.io/ubuntu
ADD run_container /
ENTRYPOINT ["/bin/bash", "-c", "/run_container \"$@\"", "--"]
16
jkh

Si vous voulez l'exécuter @build time:

CMD /bin/bash /file.sh arg1

si vous voulez l'exécuter @ run time:

ENTRYPOINT ["/bin/bash"]
CMD ["/file.sh", "arg1"]

Puis dans le shell hôte

docker build -t test .
docker run -i -t test
4
Gilles Quenot

Une autre option...

Pour que cela fonctionne

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

dans dockerfile

ENTRYPOINT ["/entrypoint.sh"]

dans 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
wagnermarques