Shell – Send command to the shell via Makefile

makeshellshell-script

I'm building a Makefile to automate the start of docker on osx.

At the end of the start docker requires to launch this command on the shell in order to configure the shell: eval "$(docker-machine env dev)"

The problem is that if I try to run it on the Makefile, this has no effect on the shell.
In fact, if the launch:
make start and then make status I get error from docker.

This is my 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

Is there a way to launch the eval "$(docker-machine env dev)" command on the Makefile and that will affect the shell?

Best Answer

  1. If you don't have dependencies to track, Make is probably not the right tool.

  2. Make launches one shell per command (or per rule in some versions), if you need to configure the shell, you'll need to configure each instances.

  3. It is not possible for a process to modify its parent. So if you wanted for the Make to modify the shell in which it has been executed, that's not possible without using the same kind of trick as docker.

  4. As $ is interpreted by Make, to have it passed to the shell it needs to be escaped.

  5. Here is a structure which could be workable (note that I combine the rules into one command), but again I don't think Make is the right tool for such kind of thing and I know nothing about docker so I may miss something relevant.

    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
    
Related Question