Skip to main content
Solved

Help with a DO loop scripyt


Forum|alt.badge.img+9

When it comes to scripting I'd say I'm mediocre compared to most folks so I need some help really nailing down a DO loop which I don't really use very often.

Purpose of the script: We use ARD to remote into machines so we populate ARD Field #1 on our machines to with the asset tag number that applies to the machine; found on a sticker on the bottom of the laptop. We're looking at moving over to DEP and I'll need a way for the user to enter the asset tag number for us since we, as techs, are no longer doing since we're not building the machine any longer.

I'd like for the script to basically not exit until the user has entered an integer into Cocoa Dialog field that is appearing on screen. It's mostly working but it's definitely not pretty and the pop-ups are not appearing in the order I'd like every single time.

1#!/bin/bash
2
3## Global Variables
4CD="/Applications/Utilities/CocoaDialog.app/Contents/MacOS/CocoaDialog"
5jamfHelper='/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper'
6icon='/Users/Shared/icon.png'
7
8## Global functions
9enterTag()
10{
11tag=`"${CD}" standard-inputbox --title "Asset Tag Number Required" --informative-text "Please enter the asset tag number of your computer" --text "Your asset tag can be found on the bottom of your laptop." --float --no-cancel | tail -1`
12
13if [[ $tag =~ ^-?[0-9]+$ ]]; then
14 intCheck="0"
15else
16 "${jamfHelper}" -windowType utility -icon "$icon" -title "Incorrect Asset Tag Entered" -description "Letters are not allowed in your asset tag. Please re-enter your asset tag using only numbers" -button1 "OK" -defaultButton 1
17 intCheck="2"
18fi
19}
20
21## Run the function
22enterTag
23echo "pre-loop"
24
25while [[ $intCheck == "2" ]]; do
26 enterTag
27 echo "first do loop"
28done
29
30tagConfirm=`"${CD}" msgbox --title "Asset Tag Confirmation" --informative-text <<EOF "You said you're asset tag is: $tag.
31Is that correct?" EOF --button1 "Yes" --button2 "No" --string-ouput`
32
33while [ $tagConfirm == "2" ]; do
34 echo "second do loop"
35 enterTag
36 tagConfirm=`"${CD}" msgbox --title "Asset Tag Confirmation" --informative-text <<EOF "You said you're asset tag is: $tag.
37Is that correct?" EOF --button1 "Yes" --button2 "No" --string-ouput`
38
39 while [ "$intCheck" = "2" ]; do
40 echo "third do loop"
41 enterTag
42 tagConfirm=`"${CD}" msgbox --title "Asset Tag Confirmation" --informative-text <<EOF "You said you're asset tag is: $tag.
43Is that correct?" EOF --button1 "Yes" --button2 "No" --string-ouput`
44 done
45done
46
47#/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -computerinfo -set1 -1 $tag

Any help would be greatly appreciated!
Thanks!
Chris

Best answer by mm2270

Hey @cgiordano I can offer some advice on this. I would consider rewriting this into a couple of functions within the script and then calling them when needed. You may not be aware of it, but a function can be called or re-run by a result returned within the function itself, which can create the kind of loop you're looking for, I believe.

I took a little time to rewrite your script using just cocoaDialog only, although you could certainly try to incorporate jamfHelper into this if you really want to. I'm also using the last beta 3 version of cocoaDialog, which has some extra features I'm using below, such as value-required and empty-text The value-required flag is used with things like inputbox and other window types to ensure a value is entered or a box selected, etc before confirming with a button. Meaning it's impossible to click OK or Enter and have an empty value in the field. The dialog won't allow it. The empty-text flag is used to customize the sheet that appears when no value is detected.

In the below, you'll see I broke this up into 2 functions. The first one calls the asset tag enter dialog, then checks to see if the value returned is an integer. Here. I'm doing some simple math by dividing the value entered by itself, which will always yield "1" if it's an integer. If that fails, it calls the function again, but in order to make the text appear differently, it sets a loop flag, which gets checked each time the function is run and sets either the error text for the dialog, or the original text. If the value entered is good, it clears the loop flag in preparation for if it gets called again.
From there, it pops up the confirmation dialog, checks for which button was clicked and if the user clicks No, it calls the original function to enter the asset tag again. If they click Yes, it moves onto setting the tag in the ARD field. In this way, you can keep going round and round almost indefinitely. For example, enter "123" then click No on the confirmation, then enter "456" then click No again and enter "789" and so on and so until the integer value is confirmed by clicking "Yes"

I added comments to most items so it's easy (hopefully) to see what's actually going on.
Give this script a try to see how it works for you. I would suggest getting the CD 3 beta version though since I can't predict how it will work under the 2.x release.

1#!/bin/bash
2
3## Path to cocoaDialog binary
4CD="/Library/Application Support/JAMF/bin/cocoaDialog.app/Contents/MacOS/cocoaDialog"
5
6function checkTag ()
7{
8
9## Display dialog asking for confirmation that the tag entered was correct
10confirmTag=$("$CD" msgbox
11 --title "Asset Tag Confirmation"
12 --text "Confirm Asset Tag"
13 --informative-text "You said you're asset tag is: $tag
14
15Is that correct?"
16 --button1 " Yes "
17 --button2 " No "
18 --icon info)
19
20## Check the button clicked
21if [ "$confirmTag" == "1" ]; then
22 echo "Tag was confirmed by user"
23
24 ## User confirmed. Write the value entered into the ARD info field for the system
25 #/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -computerinfo -set1 -1 $tag
26elif [ "$confirmTag" == "2" ]; then
27 ## User clicked No. Re-run the function to ask for the asset tag
28 echo "Re-running enter asset tag"
29 enterTag
30fi
31
32}
33
34
35function enterTag ()
36{
37
38## Default title string for dialog
39Title="Asset Tag"
40
41## If the loop flag is set, set the dialog strings to the error values
42if [ "$loop" ]; then
43 Text="Incorrect Asset Tag Entered.
44
45Letters are not allowed in your asset tag. Please re-enter your asset tag using only numbers"
46else
47 ## If the loop flag is NOT set, set the dialog strings to their normal values
48 Text="Asset Tag Number Required.
49
50Please enter the asset tag number of your computer"
51fi
52
53## Display dialog asking for asset tag value
54tag=$("${CD}" inputbox
55 --title "$Title"
56 --text ""
57 --informative-text "$Text"
58 --button1 " Enter "
59 --value-required
60 --empty-text "You must enter a value to continue"
61 --icon computer
62 --quiet)
63
64## Run a math function to determine if the value entered was an integer
65## Divides the value by itself, which will always be "1" if an integer, or error if not
66
67check=$(expr $tag / $tag 2>/dev/null)
68
69## Check on the value returned from above
70if [[ "$check" == "1" ]]; then
71 echo "Integer entered. Continuing."
72 ## Blank out the loop flag
73 loop=""
74 ## Run the checkTag function
75 checkTag
76else
77 echo "Non-integer entered. Re-run function"
78 ## Set the loop flag
79 loop="Yes"
80 ## Run the enterTag function again
81 enterTag
82fi
83
84}
85
86## Starts here. Run the function asking for the asset tag
87enterTag
View original
Did this topic help you find an answer to your question?

4 replies

mm2270
Forum|alt.badge.img+24
  • Legendary Contributor
  • 7886 replies
  • Answer
  • June 28, 2017

Hey @cgiordano I can offer some advice on this. I would consider rewriting this into a couple of functions within the script and then calling them when needed. You may not be aware of it, but a function can be called or re-run by a result returned within the function itself, which can create the kind of loop you're looking for, I believe.

I took a little time to rewrite your script using just cocoaDialog only, although you could certainly try to incorporate jamfHelper into this if you really want to. I'm also using the last beta 3 version of cocoaDialog, which has some extra features I'm using below, such as value-required and empty-text The value-required flag is used with things like inputbox and other window types to ensure a value is entered or a box selected, etc before confirming with a button. Meaning it's impossible to click OK or Enter and have an empty value in the field. The dialog won't allow it. The empty-text flag is used to customize the sheet that appears when no value is detected.

In the below, you'll see I broke this up into 2 functions. The first one calls the asset tag enter dialog, then checks to see if the value returned is an integer. Here. I'm doing some simple math by dividing the value entered by itself, which will always yield "1" if it's an integer. If that fails, it calls the function again, but in order to make the text appear differently, it sets a loop flag, which gets checked each time the function is run and sets either the error text for the dialog, or the original text. If the value entered is good, it clears the loop flag in preparation for if it gets called again.
From there, it pops up the confirmation dialog, checks for which button was clicked and if the user clicks No, it calls the original function to enter the asset tag again. If they click Yes, it moves onto setting the tag in the ARD field. In this way, you can keep going round and round almost indefinitely. For example, enter "123" then click No on the confirmation, then enter "456" then click No again and enter "789" and so on and so until the integer value is confirmed by clicking "Yes"

I added comments to most items so it's easy (hopefully) to see what's actually going on.
Give this script a try to see how it works for you. I would suggest getting the CD 3 beta version though since I can't predict how it will work under the 2.x release.

1#!/bin/bash
2
3## Path to cocoaDialog binary
4CD="/Library/Application Support/JAMF/bin/cocoaDialog.app/Contents/MacOS/cocoaDialog"
5
6function checkTag ()
7{
8
9## Display dialog asking for confirmation that the tag entered was correct
10confirmTag=$("$CD" msgbox
11 --title "Asset Tag Confirmation"
12 --text "Confirm Asset Tag"
13 --informative-text "You said you're asset tag is: $tag
14
15Is that correct?"
16 --button1 " Yes "
17 --button2 " No "
18 --icon info)
19
20## Check the button clicked
21if [ "$confirmTag" == "1" ]; then
22 echo "Tag was confirmed by user"
23
24 ## User confirmed. Write the value entered into the ARD info field for the system
25 #/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -configure -computerinfo -set1 -1 $tag
26elif [ "$confirmTag" == "2" ]; then
27 ## User clicked No. Re-run the function to ask for the asset tag
28 echo "Re-running enter asset tag"
29 enterTag
30fi
31
32}
33
34
35function enterTag ()
36{
37
38## Default title string for dialog
39Title="Asset Tag"
40
41## If the loop flag is set, set the dialog strings to the error values
42if [ "$loop" ]; then
43 Text="Incorrect Asset Tag Entered.
44
45Letters are not allowed in your asset tag. Please re-enter your asset tag using only numbers"
46else
47 ## If the loop flag is NOT set, set the dialog strings to their normal values
48 Text="Asset Tag Number Required.
49
50Please enter the asset tag number of your computer"
51fi
52
53## Display dialog asking for asset tag value
54tag=$("${CD}" inputbox
55 --title "$Title"
56 --text ""
57 --informative-text "$Text"
58 --button1 " Enter "
59 --value-required
60 --empty-text "You must enter a value to continue"
61 --icon computer
62 --quiet)
63
64## Run a math function to determine if the value entered was an integer
65## Divides the value by itself, which will always be "1" if an integer, or error if not
66
67check=$(expr $tag / $tag 2>/dev/null)
68
69## Check on the value returned from above
70if [[ "$check" == "1" ]]; then
71 echo "Integer entered. Continuing."
72 ## Blank out the loop flag
73 loop=""
74 ## Run the checkTag function
75 checkTag
76else
77 echo "Non-integer entered. Re-run function"
78 ## Set the loop flag
79 loop="Yes"
80 ## Run the enterTag function again
81 enterTag
82fi
83
84}
85
86## Starts here. Run the function asking for the asset tag
87enterTag

Forum|alt.badge.img+7
  • Contributor
  • 50 replies
  • June 28, 2017
1 assetNumber=$(osascript -e 'display dialog "Enter Asset Number:" default answer "" giving up after 86400 with text buttons {"OK"} default button 1' -e 'return text returned of result')
2 until [[ $assetNumber =~ ^-?[0-9]+([.][0-9]+)?$ ]]
3 do assetNumber=$(osascript -e 'display dialog "Invalid Asset Number. Try again:" default answer "" giving up after 86400 with text buttons {"OK"} default button 1' -e 'return text returned of result')
4 done

Or a basic loop that verifies

1#!/usr/bin/env bash
2
3getAssetNumber() {
4 assetNumber=$(osascript -e 'display dialog "Enter Asset Number:" default answer "" giving up after 86400 with text buttons {"OK"} default button 1' -e 'return text returned of result')
5 until [[ $assetNumber =~ ^-?[0-9]+([.][0-9]+)?$ ]]
6 do assetNumber=$(osascript -e 'display dialog "Invalid Asset Number. Try again:" default answer "" giving up after 86400 with text buttons {"OK"} default button 1' -e 'return text returned of result')
7 done
8 verify=$(osascript -e 'display dialog "Confirm Asset Number:" default answer "" giving up after 86400 with text buttons {"Confirm"} default button 1' -e 'return text returned of result')
9}
10
11getAssetNumber
12until [[ $verify = $assetNumber ]]
13do getAssetNumber
14done

Forum|alt.badge.img+13
  • Honored Contributor
  • 253 replies
  • June 29, 2017

@mm2270 Is a rock star


Forum|alt.badge.img+9
  • Author
  • Contributor
  • 57 replies
  • July 3, 2017

Wow. These are both really great solutions. I was clearly trying to over complicate the process. I'm UNTIL and WHILE loops and cycling functions are definitely power tools that I just need more time and experience with. I really appreciate you both taking the time to help me out.

I will say that I went with @grepoli's solution for the time being because I had some of what he suggested already in place but once the beta features are rolled into the CD release I'll probably rollover to @mm2270.

Thanks again to you both!


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