Speeding up do shell script

asobjc

(Phil Stokes) #21

It just needed the OR to be scoped with parens.

BTW, that’s some pretty fancy sed you’ve got there. :clap:
Waaaaay beyond my abilities. :exploding_head:


(Nigel Garvey) #22

How extraordinary! That had literally just occurred to me (finally, after 22 hours of fretting over your result :man_facepalming:) and I was just about to test it when your message appeared in the thread! :open_mouth:

Thanks. :slight_smile: The first line’s just to insert the “Deleted User List:” header. It would be simpler just to “echo” it earlier in the shell script:

do shell script "echo 'Login User List:' ; dscl . list /Users UniqueID | egrep -v ^'_|daemon|nobody|root' ; echo '\\nDeleted User List:' ; (defaults read /Library/Preferences/com.apple.preferences.accounts || echo '')  | sed -En '
/:RealName/ {
	N
	s/^[^=]+= |.$//g
	s/.\\n[^=]+= /'$'\\t\\t\\t''/p
}'"

(Phil Stokes) #23

Yeah, I didn’t know you could do closures like that in sed. I’ll have to dig out my old O’Reilly sed & awk book now!

Love that stuff, just never have enough need of much more than simple substitutions to learn the more advanced bits.


(Nigel Garvey) #24

If you weren’t too concerned about legibility, you could use semicolons instead of linefeeds and amaze your friends with a one-liner. :wink:

sed can be quite fun if you enjoy solving problems because of its limited (and initially strange) command set, single storage space, and — in the macOS implementation — limited regex capability and eight-bit-only character recognition. It can test one’s ingenuity to the limit! :slight_smile:


(Jim Underwood) #25

I can reduce that to 0.02 sec in SD6, if I don’t need the ID, using this simple script:

tell application "System Events"
  set userList to name of every user
end tell

userList

Which begs the question: Why do you need the userid?
The above method can also return user’s fullname and home folder.

Just curious. :smile:


(Phil Stokes) #26

As I said somewhere up thread, most people wouldn’t, but for security and sys admin considerations the uid is often useful and sometimes essential.


(Shane Stanley) #27

FWIW, here’s a version that uses ASObjC for the property list parsing. Script Geek suggests it’s around 15-20% faster.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set currentUsers to "Login User List:" & return
set currentUsers to currentUsers & (do shell script "dscl . list /Users UniqueID | egrep -v ^'_|daemon|nobody|root'")
set theData to current application's NSData's dataWithContentsOfFile:"/Library/Preferences/com.apple.preferences.accounts.plist"
if theData is not missing value then
	set currentUsers to currentUsers & return & return & "Deleted User List:" & return
	set {theThing, theError} to current application's NSPropertyListSerialization's propertyListWithData:theData options:0 |format|:(missing value) |error|:(reference)
	if theThing is missing value then error (theError's localizedDescription() as text) number -10000
	set theNames to theThing's valueForKeyPath:"deletedUsers.dsAttrTypeStandard:RealName"
	set theIDs to theThing's valueForKeyPath:"deletedUsers.dsAttrTypeStandard:UniqueID"
	repeat with i from 1 to count of theNames
		set currentUsers to currentUsers & item i of theNames & tab & tab & tab & item i of theIDs & return
	end repeat
end if

(Phil Stokes) #28

Thanks, that’s nice example code for how to read plists in Cocoa.


(Nigel Garvey) #29

Nice, and probably OK for Phil’s purposes, although for full compatibility with the previous scripts, it needs a catch for the possible non-existence of com.apple.preferences.accounts.plist.


(Shane Stanley) #30

Right — I’ve modified it accordingly.