Search code examples
gitlabgitlab-ci

Gitlab: How to pass variable containing "$" special characters to another stage?


In Gitlab, need to pass a variable containing special character "$" to another stage via artifacts.

What I tried:

build:
  stage: build
  script:
    - my_var='Admini$trator'
    - echo "pass=$my_var" >> build.env
  artifacts:
    reports:
      dotenv: build.env 

test:
  stage: test
  needs:
    - job: build
      artifacts: true
  script:
    - echo $pass 

The output is "Admini" instead of "Admini$trator". I also tried escaping with backslash "Admini\$trator" but I get "Admini\".

What is the correct way to escape artifact variables?

Later edit: Also tried pass=$${my_var} and echo 'pass=$my_var'


Solution

  • I found a solution. This might be the most dirty workaround I ever did:

    1. surround "$" with backslashes: my_var='Admini\$\trator'

      What it does: it escapes "$" in stage 1 and prevents the variable substitution in stage 2. In stage 2 the variable value will become: 'Admini$\trator'

    2. replace "$\" with "$". I used python for this:

      pass=$(python -c "s='$pass'.replace('\$\\\\', '\$'); print (s)")

    Overall:

    build:
      stage: build
      script:
        - my_var='Admini\$\trator'
        - echo "pass=$my_var" >> build.env
      artifacts:
        reports:
          dotenv: build.env 
    
    test:
      stage: test
      needs:
        - job: build
          artifacts: true
      script:
        - pass=$(python -c "s='$pass'.replace('\$\\\\', '\$'); print (s)")
        - echo $pass # outputs Admini$trator correctly
    

    If you have a string containing other special characters you can use this function inside stage 1:

        script:
            - |
              escape_special_characters() {
                local input="$1"
                local escaped_string
                local result
        
                escaped_string=$(printf '%q' "$input")
                result=$(python3 -c "s='$escaped_string'.replace('\\\\\$','\$\\\\'); print(s)") # Replace '\$' with '$\'
                
                echo "$result"
              }
            - echo escaped_pass=$(escape_special_characters "$pass") >> build.env