Help cleaning up API call For Asset tag/Position/Building

kbreed27
Contributor

Hey JAMF-er's.

 

This is probably an easy one but I'm still not super versed in scripting. I've cobbled together an script that Makes calls the Classic API to get the position, building, and asset tag information from a computer record. 

Here are the lines I am using to accomplish this:

position=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/location/position/text()")
location=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/location/building/text()")
asset=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/general/asset_tag/text()")

It all works as intended, but s there a way to combine these lines so it's not authenticating to the server 3 times to get the information? Or maybe the better question is does it even matter? I'm imaging if it doesn't have to authenticate it would speed the script up a little bit?  Or should I just leave it as is and go about my life.

1 ACCEPTED SOLUTION

talkingmoose
Moderator
Moderator

I took your commands and appended the time command to the beginning of each to get an idea for how long it took each to run. Then I rewrote your commands to make one API call and parse it for the three pieces of data.

Your commands = 1.926 seconds

My commands = 0.843 seconds

So, you can save a second for each time you run your script. If you’re processing dozens or hundreds of computers, you’ll definitely be saving significant time.

Time your commands:

 

time position=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/location/position/text()")
time location=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/location/building/text()")
time asset=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/general/asset_tag/text()")

 

Then time my commands:

 

time theXML=$( /usr/bin/curl \
--silent \
--header "Authorization: Bearer $token" \
--header "Accept: text/xml" \
--url $jssurl/JSSResource/computers/serialnumber/$serial )

time position=$( /usr/bin/xpath -e "/computer/location/position/text()" 2>/dev/null <<< "$theXML" )
time location=$( /usr/bin/xpath -e "/computer/location/building/text()" 2>/dev/null <<< "$theXML" )
time asset=$( /usr/bin/xpath -e "/computer/general/asset_tag/text()" 2>/dev/null <<< "$theXML" )

 

 See if you find a noticeable difference.

View solution in original post

4 REPLIES 4

talkingmoose
Moderator
Moderator

I took your commands and appended the time command to the beginning of each to get an idea for how long it took each to run. Then I rewrote your commands to make one API call and parse it for the three pieces of data.

Your commands = 1.926 seconds

My commands = 0.843 seconds

So, you can save a second for each time you run your script. If you’re processing dozens or hundreds of computers, you’ll definitely be saving significant time.

Time your commands:

 

time position=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/location/position/text()")
time location=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/location/building/text()")
time asset=$(/usr/bin/curl -s -H "Authorization: Bearer $token" $jssurl:8443/JSSResource/computers/serialnumber/$serial -H "accept: text/xml" | /usr/bin/xpath -e "/computer/general/asset_tag/text()")

 

Then time my commands:

 

time theXML=$( /usr/bin/curl \
--silent \
--header "Authorization: Bearer $token" \
--header "Accept: text/xml" \
--url $jssurl/JSSResource/computers/serialnumber/$serial )

time position=$( /usr/bin/xpath -e "/computer/location/position/text()" 2>/dev/null <<< "$theXML" )
time location=$( /usr/bin/xpath -e "/computer/location/building/text()" 2>/dev/null <<< "$theXML" )
time asset=$( /usr/bin/xpath -e "/computer/general/asset_tag/text()" 2>/dev/null <<< "$theXML" )

 

 See if you find a noticeable difference.

@talkingmoose thank you so much for looking at this, that makes sense. I did imagine it would make some amount of time difference. 

On the API call, what is the "--silent \" line doing exactly?

Also, I know $theXML is the information from the computer record, but I'm not quite understanding  the "2>/dev/null <<<" part of the script. 

The --silent option is the same as the -s option you were using for curl. (The shorter version is fine for working directly in Terminal where I may want to save a few keystrokes, but I like using the longer version in scripts for readability and understandability.) It suppresses a progress meter that curl shows when accessing websites.

The 2>/dev/null piece sends extraneous output from the command to the left to a bin bucket. A command like /usr/bin/xpath will sometimes show the result it generates along with extra information that’s from its own operations. This is really two pieces of information displayed together and can get confusing if we don’t filter it out.

For example, I want my output in Terminal to return position, location and asset like this:

Manager
location
asset

But if I leave out 2>/dev/null my output in Terminal will show something like this:

Found 1 nodes in stdin:
-- NODE --
Found 1 nodes in stdin:
-- NODE --
Found 1 nodes in stdin:
-- NODE --
Manager
location
asset

The node information is feedback from the /usr/bin/curl command that I don’t care to see. I don’t think this affects the variables in any way. It just keeps my window clean.

Finally, the <<< signs are a type of redirect. You’re already familiar with a pipe symbol | that takes the output from the command on the left and pipes it into the command on the right:

command 1 | command 2

The <<< signs do the same thing in the reverse order when I’m using a variable. I can put my XML into a variable. Then I can redirect the contents of my variable into a command:

command 2 <<< "$variable"

That mostly makes sense to me! Thank so much for taking your time to reply to this.