0

I have this bash script that lists all the jobs on jenkins. I have jobs with spaces within them and some without.

#!/bin/bash
for job in $(java -jar jenkins-cli.jar -s $JENKINS_URL -auth admin:admin list-jobs)
do
    file_name="$(echo "$job" | sed 's/ /-/g').xml"
    echo $file_name
    java -jar jenkins-cli.jar -s $JENKINS_URL get-job $job > $file_name
done

I have jobs called for example:

  • new job
  • test-job

When I run this script however I get the following result:

new.xml
job.xml
test-job.xml

Instead I would like to output:

new-job.xml
test-job.xml

What am I missing here?

TheWalkingMalteser
  • 561
  • 1
  • 9
  • 25
  • 1
    As the bash tag you used instructs - "For shell scripts with syntax or other errors, please check them at https://shellcheck.net before posting them here.", See also https://mywiki.wooledge.org/BashFAQ/001 – Ed Morton Jan 30 '23 at 13:17
  • 1
    See the accepted answer here: https://stackoverflow.com/questions/73668255/bash-looping-through-lines-in-a-file-and-using-the-index-of-each-line-enumera/73668345#73668345 – j_b Jan 30 '23 at 19:06

2 Answers2

2

Bash for loops splits when they see any whitespace like space, tab, or newline. So, you should use IFS (Internal Field Separator)

If lines end with "\n", try adding IFS=$'\n' before the loop (you can use unset IFS to reset it later)

You have a lot of examples here: How do I split a string on a delimiter in Bash?

Atxulo
  • 466
  • 3
  • 7
2

Space is also assigned to IFS by default and is respected during word splitting.

There are three common solutions here: First is to set IFS to $'\n' temporarily, as already suggested by Atxulo. Second is to use a while read loop against a process substitution instance, which is useful for large or indefinite inputs. Third is to use readarray which stores all input to an array. This one I believe being most practical to your problem.

readarray -t jobs < <(java ...)

for job in "${jobs[@]}"; do

Your script also has other issues. First is unnecessary use of sed. Just use ${param//pat/rep}. You also allow multiple variables to undergo word splitting unnecessarily. Quote them.

Read the Bash manual for details.

konsolebox
  • 72,135
  • 12
  • 99
  • 105