0

I have below step to go through for loop. However I'm getting below synatx error.

Code:

steps:
  arti_lib_deploy:
    stage: build image
    type: freestyle
    title: "Deploy Libs to Artifactory"
    image: 'hub.artifactory.gcp.xxxx/curlimages/curl:latest'
    commands:
      - LIB_FOLDERS=["lib1","lib2"]
      - >
        for LIB_FOLDER in "${LIB_FOLDERS[@]}"; do
         echo "FolderName- ${LIB_FOLDER}"
         curl -X GET -kv https://xxxx.service.test/entitlements/effPermissions?permissionId= "${LIB_FOLDER}"
        done

Error:

Executing command: LIB_FOLDERS=["lib1","lib2"]
[2023-08-06T10:54:14.700Z] ------------------------------
Executing command: for LIB_FOLDER in "${LIB_FOLDERS[@]}"; do
echo "FolderName-${LIB_FOLDER }"
done

[2023-08-06T10:54:14.701Z] /bin/sh: syntax error: bad substitution
[2023-08-06T10:54:15.036Z] Reading environment variable exporting file contents.[2023-08-06T10:54:15.052Z] Reading environment variable exporting file contents.[2023-08-06T10:54:16.224Z] [SYSTEM]
Message
Failed to run freestyle step: Deploy Libs to Artifactory
Caused by
Container for step title: Deploy Libs to Artifactory, step type: freestyle, operation: Freestylestep. 
Failed with exit code: 2
Documentation Link https://codefresh.io/docs/docs/codefresh-yaml/steps/freestyle/
Exit code
2
Name
NonZeroExitCodeError

Sh command:

 commands:
   - LIB_FOLDERS="lib1 lib2"
   - for LIB_FOLDER in $LIB_FOLDERS;
     do
      echo "FolderName- $LIB_FOLDER"
     done

Error:

Executing command: LIB_FOLDERS="lib1 lib2"
------------------------------
/bin/sh: syntax error: unexpected end of file (expecting "done")
[2023-08-06T23:48:22.532Z] Reading environment variable exporting file contents.
[2023-08-06T23:48:22.543Z] Reading environment variable exporting file contents.
Shabar
  • 2,617
  • 11
  • 57
  • 98
  • I'm not familiar with Codefresh, but the `"${LIB_FOLDERS[@]}"` syntax is specific to bash, and `/bin/sh` apparently is not bash on your system (it typically isn't). Either avoid bash-specific features or figure out how to get CodeFresh to use bash rather than `/bin/sh`. – Keith Thompson Aug 06 '23 at 23:41
  • @KeithThompson I tried `sh` command as well (Updated in the question). – Shabar Aug 07 '23 at 00:07
  • 1
    You don't need both the the semicolon and the newline before the `do` keyword, but I don't think that's the problem. Maybe you need to put the command on one line? `for LIB_FOLDER in $LIB_FOLDERS ; do echo "FolderName- $LIB_FOLDER" ; done` – Keith Thompson Aug 07 '23 at 00:30
  • I'm speculating that each command prefixed by `- ` is sent to `/bin/sh` individually. There may also be a way to get Codefresh to include newlines in a command, but it's not necessary here. – Keith Thompson Aug 07 '23 at 00:33
  • 1
    @KeithThompson One-line works!!!!. Please add as the answer. Cheers – Shabar Aug 07 '23 at 00:58

2 Answers2

1

I'm not familiar with Codefresh, but your question gives me some vague ideas about how it interacts with the shell.

Your original code has "${LIB_FOLDERS[@]}" in one of the commands. That's bash-specific syntax (it expands to all the elements of the LIB_FOLDERS array), but the error message indicates that Codefresh uses /bin/sh. Apparently /bin/sh is not bash on your system (it typically isn't); perhaps it's ash or dash.

One solution would be to avoid bash-specific commands. Another would be to figure out how to persuade Codefresh to use bash rather than /bin/sh. Or you could probably write an external bash script that's invoked as a command.

Your second attempt, after some comments was this:

 commands:
   - LIB_FOLDERS="lib1 lib2"
   - for LIB_FOLDER in $LIB_FOLDERS;
     do
      echo "FolderName- $LIB_FOLDER"
     done

which gave:

/bin/sh: syntax error: unexpected end of file (expecting "done")

This suggests that each command preceded by - is passed to /bin/sh separately. One solution is to write the loop in a single line, for example:

 commands:
   - LIB_FOLDERS="lib1 lib2"
   - for LIB_FOLDER in $LIB_FOLDERS ; do echo "FolderName- $LIB_FOLDER" ; done

And again, if this gets too complicated, it might be best to put the commands in an external script. Note in particular that lib1 and lib2 happen to be single words, so combining them into a string that you then split works. If there were spaces in those folder names, you'd have to do something more complicated.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
0

Same code works with multilines in Codefresh as below:

commands:
   - LIB_FOLDERS="lib1 lib2"
   - >
     for LIB_FOLDER in $LIB_FOLDERS; 
      do echo "FolderName- $LIB_FOLDER";
     done
Shabar
  • 2,617
  • 11
  • 57
  • 98