Skip to main content
Solved

Loop through 2 arrays with bash


anverhousseini
Forum|alt.badge.img+11

Hi Guys

We use a multi context environment. For deploying scripts, packages etc. on all contexts I am using the API. I'm currently working on a shell script which contains 2 arrays (contexts and the XML's). How do I loop through those two arrays without creating a huge script? I created this so far:

#!/bin/bash

#   variables
    jss=https://jss.example.com:8443
    user=example
    password=example
    filepath=~/Scripts/
    jssresource=JSSResource/scripts/id/0

#   all xml in one array
    xml=(
        'script1.xml'
        'script2.xml'
        'script3.xml'
        'script4.xml'
        'script5.xml'
    )

#   all context in one array
    context=(
        'test1'
        'test2'
        'test3'
        'test4'
        'test5'
    )

#   loop through context and XML
    /bin/echo "`date`: Loop through context and XML"

    for ((i = 0; i < "${#context[@]}"; i++))

        do

            /bin/echo "`date`: POST ${filepath}/${xml[$i]} to ${jss}/${context[$i]}"
            /usr/bin/curl -k -v -u "$user":"$password" "$jss/${context[$i]}/$jssresource" -T "$filepath"/"${xml[$i]}" -X POST

        done

#   exit
    exit 0

But from here my bash experience stops. Any hints how do I finish this sript?

Best answer by mm2270

@anverhousseini If the issue is what I mentioned above, the trick is you need to include an additional for loop within the one you have that handles all the items in the scripts array. But you have to specify a different character as a placeholder for the array indices.

I copied/pasted your script into TextWrangler and added this as shown below. Give this a try. Note that I'm using f for the script indexes, and left the i for the context indexes. This separates them and allows the script to go through the first loop on one server context and stay there until it has completed going through the script arrays to completion, before moving on to the next server context.

#!/bin/bash

#   variables
    jss=https://jss.example.com:8443
    user=example
    password=example
    filepath=~/Scripts/
    jssresource=JSSResource/scripts/id/0

#   all xml in one array
    xml=(
        'script1.xml'
        'script2.xml'
        'script3.xml'
        'script4.xml'
        'script5.xml'
    )

#   all context in one array
    context=(
        'test1'
        'test2'
        'test3'
        'test4'
        'test5'
    )

#   loop through context and XML
    /bin/echo "`date`: Loop through context and XML"

    for ((i = 0; i < "${#context[@]}"; i++))

        do

        for ((f = 0; f < "${#xml[@]}"; f++))

            do
                /bin/echo "`date`: POST ${filepath}/${xml[$f]} to ${jss}/${context[$i]}"
                /usr/bin/curl -k -v -u "$user":"$password" "$jss/${context[$i]}/$jssresource" -T "$filepath"/"${xml[$f]}" -X POST

            done

        done

#   exit
    exit 0

I only tested this by commenting out the curl line so I would get the echoes back and it showed up like this in TextWrangler:

Wed Nov 25 14:28:32 EST 2015: Loop through context and XML
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test5

Edit: minor thing, but your filepath variable has a trailing slash in it, so you don't need to include it in the echo line, as its giving you double slashes in the paths as seen in the script output above.

View original
Did this topic help you find an answer to your question?

mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • November 25, 2015

I'm not seeing an issue with what you have, though I'm only glancing over it. It looks like it should be iterating through the bash indices in both arrays doing the echo and curl commands for each as you have it. Is it not doing that? If not, what is it you see it doing specifically?


Forum|alt.badge.img+8

You could run the script with one of the following to check for errors.

set -x #DEBUG - Display commands and their arguments as they are executed.
set -v #VERBOSE - Display shell input lines as they are read.
set -n #EVALUATE - Check syntax of the script but don't execute.

Just as @mm2270 said your syntax looks good except the date command where you used ` instead of the newer $( ) but that is just the way I like doing it. Either way works.


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • November 25, 2015

Ok, looking closer I think I see the issue. Is it that its only copying script1.xml to test1, and then script2.xml to test2, and so on, instead of copying all scripts 1 through 5 up to test1 and then moving on to the next context?


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • November 25, 2015

@anverhousseini If the issue is what I mentioned above, the trick is you need to include an additional for loop within the one you have that handles all the items in the scripts array. But you have to specify a different character as a placeholder for the array indices.

I copied/pasted your script into TextWrangler and added this as shown below. Give this a try. Note that I'm using f for the script indexes, and left the i for the context indexes. This separates them and allows the script to go through the first loop on one server context and stay there until it has completed going through the script arrays to completion, before moving on to the next server context.

#!/bin/bash

#   variables
    jss=https://jss.example.com:8443
    user=example
    password=example
    filepath=~/Scripts/
    jssresource=JSSResource/scripts/id/0

#   all xml in one array
    xml=(
        'script1.xml'
        'script2.xml'
        'script3.xml'
        'script4.xml'
        'script5.xml'
    )

#   all context in one array
    context=(
        'test1'
        'test2'
        'test3'
        'test4'
        'test5'
    )

#   loop through context and XML
    /bin/echo "`date`: Loop through context and XML"

    for ((i = 0; i < "${#context[@]}"; i++))

        do

        for ((f = 0; f < "${#xml[@]}"; f++))

            do
                /bin/echo "`date`: POST ${filepath}/${xml[$f]} to ${jss}/${context[$i]}"
                /usr/bin/curl -k -v -u "$user":"$password" "$jss/${context[$i]}/$jssresource" -T "$filepath"/"${xml[$f]}" -X POST

            done

        done

#   exit
    exit 0

I only tested this by commenting out the curl line so I would get the echoes back and it showed up like this in TextWrangler:

Wed Nov 25 14:28:32 EST 2015: Loop through context and XML
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test1
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test2
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test3
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test4
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test5
Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test5

Edit: minor thing, but your filepath variable has a trailing slash in it, so you don't need to include it in the echo line, as its giving you double slashes in the paths as seen in the script output above.


Forum|alt.badge.img+8

I didn't even see that another for loop was missing. I'm done for the day.

*exits stage left


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • November 25, 2015

@Snickasaurus Honestly I didn't see it at first myself, so don't feel bad :) Its a holiday weekend coming up (at least here in the US), so that's my excuse and I'm sticking to it.


Forum|alt.badge.img+8

nom nom nom turkey nom nom nom

I'm Cajun frying my first turkey this year. Words do no justice as to how excited I am inside. :-)


anverhousseini
Forum|alt.badge.img+11

@mm2270 & @Snickasaurus You both are heroes for this evening! Works perfectly! I wish you both great thanks giving. We don't know this in switzerland, so I'm still working :)


Forum|alt.badge.img+8

@anverhousseini

Mike gets all the credit.

echo "<result>SLOW CLAP</result>"

Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings