回答:
同じを使用 file.sh
#!/bin/bash
echo $1
既存のDockerfileを使用してイメージをビルドします。
docker build -t test .
引数abc
などをxyz
使用してイメージを実行します。
docker run -ti test /file.sh abc
docker run -ti test /file.sh xyz
docker run -ti test /file.sh abc
。スクリプトが実行されるはずなので、実行されないと思いますdocker run -ti test sh /file.sh abc
。shまたは/ bin / shで正しく実行されます。
このスクリプトで file.sh
#!/bin/bash
echo Your container args are: "$@"
この Dockerfile
FROM ubuntu:14.04
COPY ./file.sh /
ENTRYPOINT ["/file.sh"]
次のことができるはずです。
% docker build -t test .
% docker run test hello world
Your container args are: hello world
ENTRYPOINT ./file.sh
chmod +x file.sh
実行可能フラグを設定することを忘れないでください。
["/file.sh"]
and /file.sh
またはor の違いは何[/file.sh]
Dockerでは、この種の情報を渡す適切な方法は、環境変数を使用することです。
同じDockerfileで、スクリプトを次のように変更します
#!/bin/bash
echo $FOO
ビルド後、次のdockerコマンドを使用します。
docker run -e FOO="hello world!" test
ここにはいくつかの相互作用があります:
docker run your_image arg1 arg2
値を置き換えますCMD
とをarg1 arg2
。これは、CMDの完全な置き換えであり、CMDにさらに値を追加するものではありません。これがdocker run some_image /bin/bash
、コンテナーでbashシェルを実行することがよくある理由です。
ENTRYPOINTとCMDの両方の値が定義されている場合、dockerは2つを連結し、連結されたコマンドを実行することでコンテナーを開始します。したがって、エントリポイントをに定義するとfile.sh
、引数としてに渡される追加の引数を使用してコンテナを実行できるようになりますfile.sh
。
dockerのエントリポイントとコマンドには、シェルを起動する文字列構文と、execを実行するjson構文の2つの構文があります。シェルは、IOリダイレクション、複数のコマンドのチェーン(など&&
)、変数の置換などの処理に役立ちます。ただし、シェルは信号処理の邪魔になります(10秒の停止の遅延を見たことがある場合)。コンテナー、これが原因であることがよくあります)、エントリーポイントとコマンドを連結します。エントリポイントを文字列として定義すると、が実行されますが/bin/sh -c "file.sh"
、それだけで問題ありません。ただし、コマンドを文字列としても定義している場合は/bin/sh -c "file.sh" /bin/sh -c "arg1 arg2"
、コンテナ内でコマンドが起動されているように見えますが、あまり良くありません。これら2つのオプションの相互作用の詳細については、こちらの表をご覧ください
シェル-c
オプションは単一の引数のみを受け取ります。それ以降はすべて、その単一の引数$1
に$2
、などとして渡されますが、引数を明示的に渡さない限り、埋め込みシェルスクリプトには渡されません。つまりは/bin/sh -c "file.sh $1 $2" "arg1" "arg2"
動作しますが、/bin/sh -c "file.sh" "arg1" "arg2"
ではないであろうからfile.sh
引数なしで呼び出されます。
これらすべてをまとめると、一般的な設計は次のとおりです。
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"]
そして、あなたはそれを次のように実行します:
docker run your_image arg1 arg2
これについてはかなり詳細があります:
["bash", "--login", "-c"]
に設定してイメージ内の/ etc / profileソースを取得する実験をしましたが、後でdocker runに渡されるシェルスクリプトに引数が渡されないのではないかと疑問に思われました...あなたの答えはそれをクリアしました、ありがとう!
私が持っているのは、実際に実行するスクリプトファイルです。このscripファイルは比較的複雑な場合があります。それを「run_container」と呼びましょう。このスクリプトは、コマンドラインから引数を取ります。
run_container p1 p2 p3
単純なrun_containerは次のようになります。
#!/bin/bash
echo "argc = ${#*}"
echo "argv = ${*}"
私がやりたいのは、これを「ドッキング」した後、次のようなdockerコマンドラインのパラメーターを使用してこのコンテナーを起動できるようにすることです。
docker run image_name p1 p2 p3
そして、run_containerスクリプトをパラメーターとしてp1 p2 p3で実行します。
これは私の解決策です:
Dockerfile:
FROM docker.io/ubuntu
ADD run_container /
ENTRYPOINT ["/bin/bash", "-c", "/run_container \"$@\"", "--"]
ENTRYPOINT
配列の3番目の値を、"/run_container \"$@\""
スペースを含む引数が正しく処理されることで置き換えます(例:)docker run image_name foo 'bar baz' quux
。
@build timeで実行したい場合:
CMD /bin/bash /file.sh arg1
@run timeで実行したい場合:
ENTRYPOINT ["/bin/bash"]
CMD ["/file.sh", "arg1"]
次に、ホストシェルで
docker build -t test .
docker run -i -t test
ENTRYPOINT
ランタイムが欲しかったと思うOPにとって良い答えですが、ビルド時間変数が本当に必要な場合、この答えはうまくいきません。使用ARG
してdocker build --build-arg
docs.docker.com/engine/reference/builder/#arg
別のオプション...
これを機能させるには
docker run -d --rm $IMG_NAME "bash:command1&&command2&&command3"
dockerfile
ENTRYPOINT ["/entrypoint.sh"]
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