Makefile을 통해 쉘에 명령 보내기

Makefile을 통해 쉘에 명령 보내기

Makefiledocker 를 자동으로 시작하는 프로그램을 만들고 있습니다 osx.

시작이 끝나면 docker는 셸에서 이 명령을 시작하여 셸을 구성해야 합니다.eval "$(docker-machine env dev)"

문제는 Makefile에서 실행하려고 하면 쉘에 아무런 영향을 미치지 않는다는 것입니다.
실제로 다음을 시작하면
make startdocker make 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 명령에서.

관련 정보