# 스크립트 및 작업 로그 형식 지정

DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** GitLab.com, Self-managed, GitLab Dedicated

특별한 구문을 사용하여 [`스크립트`](index.md#script) 섹션에서 다음을 수행할 수 있습니다.

- [긴 명령 분할](#split-long-commands): 여러 줄로 구성된 명령으로 분할합니다.
- [작업 로그에 색상 코드 사용](#add-color-codes-to-script-output): 작업 로그를 확인하기 쉽도록 색상 코드를 사용합니다.
- [사용자 정의 축소 가능한 섹션 생성](../jobs/index.md#custom-collapsible-sections): 작업 로그 출력을 간소화합니다.

## `스크립트`에서 특수 문자 사용

가끔씩 `스크립트` 명령은 단일 또는 이중 인용부호로 묶여야 합니다.
예를 들어 콜론(`:`)을 포함하는 명령은 단일 인용부호(`'`)로 묶어야 합니다.
YAML 파서는 "키: 값" 쌍 대신 문자열로 텍스트를 해석해야 합니다.

다음과 같이 콜론을 사용하는 스크립트의 예시:

```yaml
job:
  script:
    - curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects"

유효한 YAML으로 간주하려면 전체 명령을 단일 인용부호로 묶어야 합니다. 명령이 이미 단일 인용부호를 사용하는 경우 가능하다면 이를 이중 인용부호(")로 변경해야 합니다:

job:
  script:
    - 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"'

구문이 올바른지 확인하려면 CI Lint 도구를 사용하세요.

또한 다음과 같은 문자를 사용할 때 주의하세요:

  • {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, `.

0이 아닌 종료 코드 무시

스크립트 명령이 0이 아닌 종료 코드를 반환하면 작업이 실패하고 추가적인 명령이 실행되지 않습니다.

이 동작을 피하려면 종료 코드를 변수에 저장하세요:

job:
  script:
    - false || exit_code=$?
    - if [ $exit_code -ne 0 ]; then echo "이전 명령이 실패했습니다"; fi;

모든 작업에 대한 기본 before_script 또는 after_script 설정

before_scriptafter_scriptdefault와 함께 사용할 수 있습니다.

  • before_scriptdefault를 함께 사용하여 모든 작업의 스크립트 명령보다 먼저 실행해야 하는 기본 명령 배열을 정의합니다.
  • after_scriptdefault를 함께 사용하여 작업이 완료된 후 실행해야 하는 기본 명령 배열을 정의합니다.

작업에서 다른 값으로 덮어쓸 수 있습니다. 기본값을 무시하려면 before_script: [] 또는 after_script: []을 사용하세요:

default:
  before_script:
    - echo "기본적으로 모든 작업에서 이 `before_script`를 실행합니다."
  after_script:
    - echo "기본적으로 모든 작업에서 이 `after_script`를 실행합니다."

job1:
  script:
    - echo "기본 `before_script` 이후에 이 스크립트가 실행되며,"
    - echo "기본 `after_script` 이전에 실행됩니다."

job2:
  before_script:
    - echo "기본 `before_script` 대신에 이 스크립트가 실행됩니다."
  script:
    - echo "작업의 `before_script` 이후에 실행되지만,"
    - echo "작업에서 기본 `after_script`을 사용하지 않습니다."
  after_script: []

긴 명령 분할

가독성을 높이기 위해 긴 명령을 여러 줄로 나눌 수 있습니다. | (리터럴) 및 > (접힌) YAML 다중 줄 블록 스칼라 표시기를 사용하세요.

경고: 여러 명령이 하나의 명령 문자열로 결합되면 마지막 명령의 실패 또는 성공만이 보고됩니다. 이전 명령에서의 실패는 버그로 인해 무시됩니다. 이를 해결하기 위해 각 명령을 별도의 script 항목으로 실행하거나 각 명령 문자열에 exit 1 명령을 추가하세요.

| (리터럴) YAML 다중 줄 블록 스칼라 표시기를 사용하여 작업 설명의 스크립트 섹션에서 명령을 여러 줄로 작성할 수 있습니다. 각 줄은 별도의 명령으로 처리됩니다. 첫 번째 명령만 작업 로그에 반복되지만 추가 명령은 여전히 실행됩니다:

job:
  script:
    - |
      echo "첫 번째 명령 줄."
      echo "두 번째 명령 줄."
      echo "세 번째 명령 줄."

위의 예시는 작업 로그에 다음과 같이 표시됩니다:

$ echo 첫 번째 명령 줄 # 접힌 다중 라인 명령
첫 번째 명령 줄
두 번째 명령 줄.
세 번째 명령 줄.

> (접힌) YAML 다중 줄 블록 스칼라 표시기는 구간 사이의 빈 줄을 새 명령의 시작으로 처리합니다:

job:
  script:
    - >
      echo "첫 번째 명령 줄
      두 줄로 분할됩니다."

      echo "두 번째 명령 줄."

이는 > 또는 | 블록 스칼라 표시기 없는 다중 라인 명령과 유사하게 작동합니다:

job:
  script:
    - echo "첫 번째 명령 줄
      두 줄로 분할됩니다."

      echo "두 번째 명령 줄."

위의 두 예시는 작업 로그에 다음과 같이 표시됩니다:

$ echo 첫 번째 명령 줄 두 줄로 분할됩니다. # 접힌 다중 라인 명령
첫 번째 명령 줄 두 줄로 분할됩니다.
두 번째 명령 줄.

> 또는 | 블록 스칼라 표시기를 생략하면 GitLab은 비어 있지 않은 줄을 연결하여 명령을 형성합니다. 결합된 명령이 실행될 수 있는지 확인하세요.

이곳에 쉘 문서|> 연산자와 함께 작동합니다. 아래 예시는 소문자를 대문자로 변환합니다:

job:
  script:
    - |
      tr a-z A-Z << END_TEXT
        one two three
        four five six
      END_TEXT

결과는 다음과 같습니다:

$ tr a-z A-Z << END_TEXT # 접힌 다중 라인 명령
  ONE TWO THREE
  FOUR FIVE SIX

## 스크립트 출력물에 색상 코드 추가하기

스크립트 출력물은 [ANSI 이스케이프 코드](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors)를 사용하거나 ANSI 이스케이프 코드를 출력하는 명령이나 프로그램을 실행하여 색을 입힐 수 있습니다.

예를 들어, [Bash와 컬러 코드](https://misc.flogisoft.com/bash/tip_colors_and_formatting)를 사용하는 방법은 다음과 같습니다:

```yaml
job:
  script:
    - echo -e "\e[31m이 텍스트는 빨간색입니다,\e[0m 하지만 이 텍스트는 아닙니다\e[31m 그러나 이 부분은 다시 빨간색입니다."

Shell 환경 변수에 색상 코드를 정의하거나 심지어 CI/CD 변수에 정의하여 명령을 읽기 쉽고 재사용 가능하게 만들 수 있습니다.

위와 같은 예시를 사용하여 동일한 예를 들어 보면, before_script에서 환경 변수를 정의합니다:

job:
  before_script:
    - TXT_RED="\e[31m" && TXT_CLEAR="\e[0m"
  script:
    - echo -e "${TXT_RED}이 텍스트는 빨간색입니다,${TXT_CLEAR} 하지만 이 부분은 아닙니다${TXT_RED} 그러나 이 부분은 다시 빨간색입니다."
    - echo "이 텍스트에는 색상이 입혀지지 않았습니다"

또는 PowerShell 색상 코드를 사용하는 방법은 다음과 같습니다:

job:
  before_script:
    - $esc="$([char]27)"; $TXT_RED="$esc[31m"; $TXT_CLEAR="$esc[0m"
  script:
    - Write-Host $TXT_RED"이 텍스트는 빨간색입니다,"$TXT_CLEAR" 하지만 이 텍스트는 아닙니다"$TXT_RED" 그러나 이 텍스트는 다시 빨간색입니다."
    - Write-Host "이 텍스트에는 색상이 입혀지지 않았습니다"

문제 해결

:를 사용하는 스크립트에서 구문이 올바르지 않음 오류

스크립트에 콜론(:)을 사용하면 GitLab이 다음과 같이 출력할 수 있습니다:

  • 구문이 올바르지 않음
  • 스크립트 구성은 문자열이거나 10단계까지 중첩된 문자열 배열이어야 합니다

예를 들어, cURL 명령어의 일부로 "PRIVATE-TOKEN: ${PRIVATE_TOKEN}"을 사용하는 경우:

pages-job:
  stage: deploy
  script:
    - curl --header 'PRIVATE-TOKEN: ${PRIVATE_TOKEN}' "https://gitlab.example.com/api/v4/projects"
  environment: production

YAML 파서는 :가 YAML 키워드를 정의한다고 생각하고 구문이 올바르지 않음 오류를 출력합니다.

콜론을 포함하는 명령을 사용하려면 전체 명령을 단일 따옴표로 감싸야 합니다. 기존의 단일 따옴표(')을 이중 따옴표(")로 변경해야 할 수도 있습니다:

pages-job:
  stage: deploy
  script:
    - 'curl --header "PRIVATE-TOKEN: ${PRIVATE_TOKEN}" "https://gitlab.example.com/api/v4/projects"'
  environment: production

스크립트에서 &&를 사용할 때 작업이 실패하지 않음

두 개의 명령을 하나의 스크립트 라인에서 결합하기 위해 &&을 사용하는 경우, 한 명령이 실패하더라도 작업이 성공적으로 반환될 수 있습니다. 예를 들어:

job-does-not-fail:
  script:
    - invalid-command xyz && invalid-command abc
    - echo $?
    - echo "이 작업은 이미 실패해야 했지만 예상치 못하게 실행됩니다."

&& 연산자는 두 명령이 실패해도 종료 코드 0을 반환하고 작업이 계속 실행됩니다. 명령이 실패하면 전체 스크립트를 종료하도록 하려면 전체 라인을 괄호로 묶어야 합니다:

job-fails:
  script:
    - (invalid-command xyz && invalid-command abc)
    - echo "작업이 이미 실패했으며 이 부분은 실행되지 않습니다."

YAML 다중 라인 블록 스칼라에 의해 다중 라인 명령이 유지되지 않음

긴 명령을 분할하기 위해 - >를 사용하여 YAML 다중 라인 블록 스칼라를 사용하는 경우, 추가 들여쓰기로 인해 각 줄이 개별 명령으로 처리될 수 있습니다.

예를 들어:

script:
  - >
    RESULT=$(curl --silent
      --header
        "Authorization: Bearer $CI_JOB_TOKEN"
      "${CI_API_V4_URL}/job"
    )

이처럼 들여쓰기로 인해 줄 바꿈이 보존되어 실패합니다:

$ RESULT=$(curl --silent # collapsed multi-line command
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
/bin/bash: line 149: --header: command not found
/bin/bash: line 150: https://gitlab.example.com/api/v4/job: No such file or directory

이를 해결하려면 다음 중 하나를 수행합니다:

  • 추가 들여쓰기를 제거합니다.

    script:
      - >
        RESULT=$(curl --silent
        --header
        "Authorization: Bearer $CI_JOB_TOKEN"
        "${CI_API_V4_URL}/job"
        )
    
  • 추가 줄 바꿈이 처리되도록 스크립트를 수정합니다. 예를 들어 셸 라인 연속을 사용합니다.

    script:
      - >
        RESULT=$(curl --silent \
          --header \
            "Authorization: Bearer $CI_JOB_TOKEN" \
          "${CI_API_V4_URL}/job")
    

작업 로그 출력 형식이 예상과 다르거나 예상치 못한 문자가 포함되어 있습니다

가끔 작업 로그의 형식이 TERM 환경 변수를 사용하여 색상이나 형식을 지정하는 도구에서 잘못 표시될 수 있습니다. 예를 들어, mypy 명령어의 경우:

예시 출력

GitLab Runner는 컨테이너의 셸을 대화형 모드가 아닌 비대화형 모드로 실행하므로, 셸의 TERM 환경 변수는 dumb로 설정됩니다. 이러한 도구들의 형식을 수정하려면 다음과 같이 할 수 있습니다:

  • 명령어를 실행하기 전에 셸의 환경에 TERM=ansi를 설정하는 추가 스크립트 라인을 추가합니다.
  • TERM CI/CD 변수에 값으로 ansi를 추가합니다.