Makefileを介してシェルにコマンドを送信する

Makefileを介してシェルにコマンドを送信する

Makefiledockerを自動的に起動するプログラムを作成していますosx

起動が完了したら、dockerはシェルでこのコマンドを起動してシェルを設定する必要があります。eval "$(docker-machine env dev)"

問題は、Makefileで実行しようとするとシェルには影響しないことです。
実際に次を起動すると、
make startdockermake 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

  1. 追跡する依存関係がない場合、Makeは正しいツールではない可能性があります。

  2. Makeは各コマンド(または一部のバージョンでは各ルール)に対してシェルを起動します。シェルを構成する必要がある場合は、各インスタンスを構成する必要があります。

  3. プロセスが親プロセスを変更することは不可能です。したがって、Makeに実行中のシェルを変更させるには、dockerと同じトリックを使用しないと不可能です。

  4. Makeが説明したように、$それをシェルに渡すにはエスケープする必要があります。

  5. これは機能する構造です(ルールを単一のコマンドにまとめたことに注意してください)。しかし、私は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コマンドで。

関連情報