Makefile
dockerを自動的に起動するプログラムを作成していますosx
。
起動が完了したら、dockerはシェルでこのコマンドを起動してシェルを設定する必要があります。eval "$(docker-machine env dev)"
問題は、Makefileで実行しようとするとシェルには影響しないことです。
実際に次を起動すると、
make start
dockermake status
でエラーが発生します。
これは私のMakefileです。
CURRENT_DIRECTORY := $(shell pwd)
start:
@sh run.sh -d
@eval $(docker-machine env dev)
start-compose:
@docker-compose up -d
clean:
@docker-compose rm --force
stop:
@docker-compose stop
shutdown:
@docker-compose stop
@docker-machine stop dev
build:
@docker-compose build
status:
@docker-compose ps
cli:
@docker-compose run --rm web bash
log:
@docker-compose logs web
logall:
@docker-compose logs
restart:
@docker-compose stop web
@docker-compose start web
restartall:
@docker-compose stop
@docker-compose start
.PHONY: clean start start-compose stop status shutdown build cli log logall restart restartall
eval "$(docker-machine env dev)"
Makefileでコマンドを起動し、そのコマンドがシェルに影響を与える方法はありますか?
答え1
追跡する依存関係がない場合、Makeは正しいツールではない可能性があります。
Makeは各コマンド(または一部のバージョンでは各ルール)に対してシェルを起動します。シェルを構成する必要がある場合は、各インスタンスを構成する必要があります。
プロセスが親プロセスを変更することは不可能です。したがって、Makeに実行中のシェルを変更させるには、dockerと同じトリックを使用しないと不可能です。
Makeが説明したように、
$
それをシェルに渡すにはエスケープする必要があります。これは機能する構造です(ルールを単一のコマンドにまとめたことに注意してください)。しかし、私はMakeがこの種の仕事に適したツールだとは思わず、私はdockerについて何も知りません。関連するものがありません。
start: @sh run.sh -d; \ echo $$(docker-machine env dev) > ./docker-config start-compose: @eval $$(cat ./docker-config); \ docker-compose up -d clean: @eval $$(cat ./docker-config); \ docker-compose rm --force stop: @eval $$(cat ./docker-config); \ docker-compose stop shutdown: @eval $$(cat ./docker-config); \ docker-compose stop ; \ docker-machine stop dev
答え2
質問を理解したら、makeが終了したときにその環境がまだ存在するように、makeがいくつかの環境でシェルを構成したいと思うでしょう。
このeval
コマンドが行うのは、現在のシェルを変更することですが、 make で実行しているので、 make によって生成されたサブシェルだけを変更してから `eval という make ターゲットが完了すると削除されます。
makeが実行するすべての行は、実際にそれが生成するシェルから呼び出されます。 makeで実行されているコマンドに戻ると、シェルとシェルで行ったすべての変更は消えます。
あなたがしなければならないのは、コマンドeval
を呼び出すために使用したdocker
すべてのシェルで同じサブシェルでコマンドを実行することです。それは、すべてこの環境が必要なターゲットで実行されるコマンドをeval
最初に呼び出す必要があります。そして、各行に対して別々のサブシェルを実行するのではなく、同じシェルでコマンドを実行する必要があります。
最も簡単な方法は、;
まず環境を設定してから、いくつかのdockerコマンドを実行するようにコマンドを一緒に接続することです。
status:
eval $$(docker-machine env dev); docker-compose ps
二重ドル記号に注意してください:makeの特殊文字であり、シェルがそれを見るためにエスケープする必要が$
あります。$$
$
これはメーカー固有のバージョンです。この回答。したがって、スクリプト、us &&
、または必要な他の名前を呼び出すこともできます。
あるいは、makeによってdocker環境が設定または変更されていない(たとえば、makeランタイム変数に基づいて環境を調整する必要はありません)、事前に決定されている場合は、docker環境が設定されたシェルでmakeを実行できます。戻る。これにより、各サブシェルにも同じ環境があります。
複数行を同じサブシェルに収集するために使用する方法があります。文書を確認してください。
答え3
私はそれを解決しました
@eval $$(docker-machine env dev); \
docker-compose stop; \
docker-machine stop dev
すべてのmakeコマンドで。