Speeding up do shell script

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:

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
}'"

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.

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:

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:

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.

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
1 Like

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

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.

Right — I’ve modified it accordingly.