1

I'm trying to figure out how to declare a variable that is an array and use it as arguments passed to a shell script. Or find out how to be a bit more DRY by learning how to

Here's what I have tried that causes /bin/sh: eval: line X: syntax error: bad substitution:

variables:
  EXTRA_ARGS: (. "${CI_COMMIT_SHORT_SHA} pipeline-${CI_PIPELINE_ID} latest" "pipeline-${CI_PIPELINE_ID}" $CI_COMMIT_REF_NAME $CI_COMMIT_REF_SLUG)

build:
  stage: build
  script:
    - path/to/script.sh uniqueParam1 uniqueParam2 ${EXTRA_ARGS[@]}
    - path/to/script.sh uniqueParam3 uniqueParam4 ${EXTRA_ARGS[@]}
    - path/to/script.sh uniqueParam5 uniqueParam6 ${EXTRA_ARGS[@]}

And the follow runs fine, but as you can tell, I'm repeating the extra arguments:

build:
  stage: build
  script:
    - path/to/script.sh uniqueParam1 uniqueParam2 . "${CI_COMMIT_SHORT_SHA} pipeline-${CI_PIPELINE_ID} latest" "pipeline-${CI_PIPELINE_ID}" $CI_COMMIT_REF_NAME $CI_COMMIT_REF_SLUG
    - path/to/script.sh uniqueParam3 uniqueParam4 . "${CI_COMMIT_SHORT_SHA} pipeline-${CI_PIPELINE_ID} latest" "pipeline-${CI_PIPELINE_ID}" $CI_COMMIT_REF_NAME $CI_COMMIT_REF_SLUG
    - path/to/script.sh uniqueParam5 uniqueParam6 . "${CI_COMMIT_SHORT_SHA} pipeline-${CI_PIPELINE_ID} latest" "pipeline-${CI_PIPELINE_ID}" $CI_COMMIT_REF_NAME $CI_COMMIT_REF_SLUG

I've also tried to remove the . dot, as an argument, but the error persists.

For my sake of mind I tried to run the concept in bash, and ran with success as follows:

#!/bin/bash

TEST1="Hello"
TEST2="human!"

ARGS=(. $TEST1 $TEST2 "${TEST2} ${TEST1}" "param1" "param2")

echo "${ARGS[*]}"

Outputs:

. Hello human! human! Hello param1 param2

Also tried to put it in the scripts as:

script:
  - EXTRA_ARGS=(. "${CI_COMMIT_SHORT_SHA} pipeline-${CI_PIPELINE_ID} latest" "pipeline-${CI_PIPELINE_ID}" $CI_COMMIT_REF_NAME $CI_COMMIT_REF_SLUG)

And also doesn't work:

/bin/sh: eval: line 92: syntax error: unexpected "("

Also tried to escape \( but did not work.

3
  • /bin/sh (most probably) is not bash. Your docker inside gitlab is not running bash. Commented Sep 27, 2019 at 23:18
  • You're absolutely right @KamilCuk I'll see if I can change the runner to bash as unix shell does not support array I think Commented Sep 28, 2019 at 0:54
  • gitlab.com/gitlab-org/gitlab-runner/issues/1758 Commented Sep 28, 2019 at 1:03

3 Answers 3

1

As pointed out by the first comment, the issue is related to the Docker image that is based in Alpine that has bourne shell and not bash by default.

https://gitlab.com/gitlab-org/gitlab-runner/issues/1758

Sign up to request clarification or add additional context in comments.

Comments

1

The following works with me for the same case, with a minor difference that I define the array as a variable instead of sending it as an argument.

In .getlab-ci.yml, I export a "string" variable that has the elements concatenated and delimited by ';' (with single quotes, escaping ;):

build:
  stage: build 
  variables:
    ELMNT1: Value Has Spaces
    ELMNT2: Another Value Has Spaces
  script: 
    - export MY_ARR_STR=${ELMNT1}';'${ELMNT2}
    - shell my_script.sh

In the script, I convert the string to an array:

my_script.sh

ORIG_IFS="$IFS"
IFS=";" read -a MY_ARR <<< $MY_ARR_STR
IFS="$ORIG_IFS"
for index in "${!MY_ARR[@]}";
do
    echo "Array Element at index '$index' is '${MY_ARR[$index]}'"
done

With output as

Array Element at index '0' is 'Value Has Spaces'
Array Element at index '1' is 'Another Value Has Spaces'

Comments

0

In sh, you can also create an array variable from a string, as shown in https://unix.stackexchange.com/questions/569471/shell-convert-string-to-array

Here is how I use it in Gitlab CI to build Docker images from the kaniko container that has sh shell:

.build-kaniko:
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: ['']
  variables:
    CONTEXT_DIR: ''
    IMAGE_DESTINATION_URI: ''
    KANIKO_EXTRA_ARGS: '--target prod --build-arg foo=bar'
  script:
    # Convert KANIKO_EXTRA_ARGS to shell array variable
    # https://unix.stackexchange.com/questions/569471/shell-convert-string-to-array
    - set -o noglob
    - IFS=' '
    - 'set -- "$KANIKO_EXTRA_ARGS"'
    - 'echo "KANIKO_EXTRA_ARGS: " "$@"'

    # Run kaniko command
    - /kaniko/executor
      --context "$CONTEXT_DIR"
      --destination "$IMAGE_DESTINATION_URI"
      --skip-unused-stages=true
      $@

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.