shell vs exec

2024. 11. 25. 15:44Docker

Dockerfile에서 명령어를 실행할 때, Shell Form(쉘 형식)과 Exec Form(exec 형식)의 두 가지 방법이 있습니다. 이 둘의 차이를 이해하는 것은 Dockerfile 작성의 핵심 중 하나입니다. 아래에서 두 형식의 차이와 장단점을 설명하겠습니다.


1. Shell Form (쉘 형식)

구문

CMD echo "Hello, World!"
  • 쉘 형식은 명령어를 /bin/sh -c를 통해 실행합니다.
  • 명령어가 문자열 형태로 전달되며, 쉘이 이를 해석하여 실행합니다.

동작 방식

  • Docker는 기본적으로 /bin/sh -c를 통해 명령을 실행합니다.
  • 복잡한 쉘 명령어(&&, ||, 파이프 |)를 사용할 수 있습니다.

장점

  1. 유연성:

    • 쉘의 모든 기능(변수 확장, 파이프, 조건문 등)을 사용할 수 있습니다.
      CMD echo "Hello" && echo "World"
  2. 짧은 명령어:

    • 하나의 문자열로 간단히 명령어를 표현할 수 있습니다.

단점

  1. 의도치 않은 동작:

    • 쉘이 명령어를 해석하기 때문에, 예기치 않은 결과가 발생할 수 있습니다.
    • 예: 공백이나 특수 문자로 인해 문제가 발생할 가능성.
  2. 성능 저하:

    • 명령어 실행 시 쉘 프로세스를 추가로 생성하므로, 오버헤드가 생깁니다.
  3. 보안 문제:

    • 명령어가 쉘을 통해 실행되므로 쉘 인젝션(shell injection) 공격에 취약할 수 있습니다.

2. Exec Form (exec 형식)

구문

CMD ["echo", "Hello, World!"]
  • Exec 형식은 명령어를 직접 실행하며, 쉘을 거치지 않습니다.
  • 명령어와 인수를 배열 형태로 전달합니다.

동작 방식

  • Docker는 명령어를 직접 실행하므로 /bin/sh -c가 포함되지 않습니다.
  • 쉘의 기능(파이프, 조건문 등)을 사용할 수 없으며, 명령어와 인수를 명시적으로 작성해야 합니다.

장점

  1. 명확성:

    • 쉘을 사용하지 않기 때문에, 명령어가 예측 가능한 방식으로 실행됩니다.
  2. 보안성:

    • 쉘 인젝션(shell injection)의 위험이 없습니다.
  3. 효율성:

    • 쉘 프로세스가 생성되지 않으므로 성능 오버헤드가 적습니다.

단점

  1. 제약:

    • 쉘의 고급 기능(파이프, 변수 확장 등)을 사용할 수 없습니다.
    • 복잡한 명령어는 별도의 스크립트로 분리해야 합니다.
  2. 가독성:

    • 긴 명령어를 배열로 작성하면 가독성이 떨어질 수 있습니다.

3. Shell vs Exec 비교

특성 Shell Form Exec Form
구문 CMD echo "Hello, World!" CMD ["echo", "Hello, World!"]
실행 방식 /bin/sh -c를 통해 실행 명령어를 직접 실행
쉘 기능 사용 가능 여부 가능 (&&, `
보안성 쉘 인젝션 가능성 있음 보안성이 높음
성능 쉘 프로세스 생성으로 약간의 오버헤드 쉘이 없어 더 효율적
유연성 높은 유연성 명령어 및 인수에 국한됨

4. 사용 사례

  • Shell Form:

    • 복잡한 쉘 명령어를 실행해야 하는 경우.
    • 예: 여러 명령어를 연결하거나 파이프(|)를 사용할 때.
      CMD echo "Step 1" && echo "Step 2"
  • Exec Form:

    • 단일 명령어나 단순한 실행을 할 때.
    • 보안 및 성능이 중요한 경우.
      CMD ["echo", "Hello, World!"]

5. Dockerfile 예제

Shell Form

FROM ubuntu:latest
CMD echo "This is Shell Form" && echo "Using /bin/sh"
  • 실행 명령:
    docker build -t shell-example .
    docker run shell-example
  • 결과:
    This is Shell Form
    Using /bin/sh

Exec Form

FROM ubuntu:latest
CMD ["echo", "This is Exec Form", "Without /bin/sh"]
  • 실행 명령:
    docker build -t exec-example .
    docker run exec-example
  • 결과:
    This is Exec Form Without /bin/sh

결론

  1. Shell Form은 쉘의 유연성을 필요로 할 때 적합합니다.
  2. Exec Form은 보안, 성능, 명령의 명확성이 중요할 때 권장됩니다.
  3. Best Practice:
    • 단순한 명령어에는 Exec Form을 사용하세요.
    • 복잡한 명령어는 쉘 스크립트로 작성하여 Exec Form으로 실행하는 것이 좋습니다.

'Docker' 카테고리의 다른 글

Docker 커맨드와 컨셉 이해  (0) 2024.12.06
Docker Compose  (0) 2024.11.29
Bridge Network  (0) 2024.11.21
Linux Name  (0) 2024.11.21
alpine  (0) 2024.11.21