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:

1#!/bin/bash
2
3# variables
4 jss=https://jss.example.com:8443
5 user=example
6 password=example
7 filepath=~/Scripts/
8 jssresource=JSSResource/scripts/id/0
9
10# all xml in one array
11 xml=(
12 'script1.xml'
13 'script2.xml'
14 'script3.xml'
15 'script4.xml'
16 'script5.xml'
17 )
18
19# all context in one array
20 context=(
21 'test1'
22 'test2'
23 'test3'
24 'test4'
25 'test5'
26 )
27
28# loop through context and XML
29 /bin/echo "`date`: Loop through context and XML"
30
31 for ((i = 0; i < "${#context[@]}"; i++))
32
33 do
34
35 /bin/echo "`date`: POST ${filepath}/${xml[$i]} to ${jss}/${context[$i]}"
36 /usr/bin/curl -k -v -u "$user":"$password" "$jss/${context[$i]}/$jssresource" -T "$filepath"/"${xml[$i]}" -X POST
37
38 done
39
40# exit
41 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.

1#!/bin/bash
2
3# variables
4 jss=https://jss.example.com:8443
5 user=example
6 password=example
7 filepath=~/Scripts/
8 jssresource=JSSResource/scripts/id/0
9
10# all xml in one array
11 xml=(
12 'script1.xml'
13 'script2.xml'
14 'script3.xml'
15 'script4.xml'
16 'script5.xml'
17 )
18
19# all context in one array
20 context=(
21 'test1'
22 'test2'
23 'test3'
24 'test4'
25 'test5'
26 )
27
28# loop through context and XML
29 /bin/echo "`date`: Loop through context and XML"
30
31 for ((i = 0; i < "${#context[@]}"; i++))
32
33 do
34
35 for ((f = 0; f < "${#xml[@]}"; f++))
36
37 do
38 /bin/echo "`date`: POST ${filepath}/${xml[$f]} to ${jss}/${context[$i]}"
39 /usr/bin/curl -k -v -u "$user":"$password" "$jss/${context[$i]}/$jssresource" -T "$filepath"/"${xml[$f]}" -X POST
40
41 done
42
43 done
44
45# exit
46 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:

1Wed Nov 25 14:28:32 EST 2015: Loop through context and XML
2Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test1
3Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test1
4Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test1
5Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test1
6Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test1
7Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test2
8Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test2
9Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test2
10Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test2
11Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test2
12Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test3
13Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test3
14Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test3
15Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test3
16Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test3
17Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test4
18Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test4
19Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test4
20Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test4
21Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test4
22Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test5
23Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test5
24Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test5
25Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test5
26Wed 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?

9 replies

mm2270
Forum|alt.badge.img+24
  • Legendary Contributor
  • 7886 replies
  • 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
  • Contributor
  • 131 replies
  • November 25, 2015

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+24
  • Legendary Contributor
  • 7886 replies
  • 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+24
  • Legendary Contributor
  • 7886 replies
  • Answer
  • 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.

1#!/bin/bash
2
3# variables
4 jss=https://jss.example.com:8443
5 user=example
6 password=example
7 filepath=~/Scripts/
8 jssresource=JSSResource/scripts/id/0
9
10# all xml in one array
11 xml=(
12 'script1.xml'
13 'script2.xml'
14 'script3.xml'
15 'script4.xml'
16 'script5.xml'
17 )
18
19# all context in one array
20 context=(
21 'test1'
22 'test2'
23 'test3'
24 'test4'
25 'test5'
26 )
27
28# loop through context and XML
29 /bin/echo "`date`: Loop through context and XML"
30
31 for ((i = 0; i < "${#context[@]}"; i++))
32
33 do
34
35 for ((f = 0; f < "${#xml[@]}"; f++))
36
37 do
38 /bin/echo "`date`: POST ${filepath}/${xml[$f]} to ${jss}/${context[$i]}"
39 /usr/bin/curl -k -v -u "$user":"$password" "$jss/${context[$i]}/$jssresource" -T "$filepath"/"${xml[$f]}" -X POST
40
41 done
42
43 done
44
45# exit
46 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:

1Wed Nov 25 14:28:32 EST 2015: Loop through context and XML
2Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test1
3Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test1
4Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test1
5Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test1
6Wed Nov 25 14:28:32 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test1
7Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test2
8Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test2
9Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test2
10Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test2
11Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test2
12Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test3
13Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test3
14Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test3
15Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test3
16Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test3
17Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test4
18Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test4
19Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test4
20Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test4
21Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script5.xml to https://jss.example.com:8443/test4
22Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script1.xml to https://jss.example.com:8443/test5
23Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script2.xml to https://jss.example.com:8443/test5
24Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script3.xml to https://jss.example.com:8443/test5
25Wed Nov 25 14:28:33 EST 2015: POST /Users/mike/Scripts//script4.xml to https://jss.example.com:8443/test5
26Wed 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
  • Contributor
  • 131 replies
  • November 25, 2015

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+24
  • Legendary Contributor
  • 7886 replies
  • 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
  • Contributor
  • 131 replies
  • November 25, 2015

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
  • Author
  • Valued Contributor
  • 98 replies
  • November 25, 2015

@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
  • Contributor
  • 131 replies
  • November 25, 2015

@anverhousseini

Mike gets all the credit.

1echo "<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