Technology

Drag and drop Terminal tabs behave the same as in Safari

Both Safari and Terminal gained drag and drop repositioning of tabs in Leopard. (True, Safari 3 also installs on Tiger as well as Microsoft Windows, but I've only used the new tab features under Leopard.) Since there has been discussion of the gestures required to reorder tabs within a window vs. drag them into new windows entirely, I wondered if the same was true for Terminal. (See Safari’s tab dragging modes and Safari 3.0: Dragging tabs up or down to move them sideways for more.)

Sure enough, I see the same results:

  • The first tab in a Terminal window can be reordered, made into a new window, or added to an existing window by dragging up, down, or left — but not to the right.
  • Dragging any other tab left or right as the first gesture only lets me reorder the tab within the same window.
  • Dragging any other tab up or down as the first gesture only lets me move it to a new window or add it as a tab in an existing window. Unlike in Safari — where a thumbnail of a Web page is rendered for drag and drop — I see an entire Terminal window rendered transparently at full size until it is dropped in the new location.

So, perhaps there is some grand design at work here, and this odd user interface is actually intentional. (It’ll probably get tied to some multi-touch trackpad action soon, right?)

Login, log in, log into, and tune out

I was reviewing the pre-release CIS guide for securing Leopard today, and was struck by the many ways people refer to the action of logging in to a computer. This is really a situation calling out for consistent usage based on a style sheet.

So, here are my personal observations on the matter:

  • Login is the noun of the bunch. The New Oxford American Dictionary (handy to use, since it’s built into the Dictionary application on Mac OS X) agrees with me here, calling it “an act of logging in to a computer system.” They also list “logon” as an alternative, and I agree. “He used his login credentials to access the system,” would be a usage example.
  • Log in is the verb form. The NOAD backs me up, listing it and “log on” as “phrasal verbs” whose meanings are, “go through the procedures to begin use of a computer system, which includes establishing the identity of the user.” For an example phrase, “Security procedures require that you log in to the computer.”
  • Log into should not be used, as far as I’m concerned. “Log onto” would be its close brethren, also to be avoided. The NOAD has no listing for either. My proposed alternatives would simply be to add a space: “log in to” or “log on to.” Then, you’re using the phrasal verb.

As I was examining the document, I decide to see what Apple does. I was using the dictionary data they bundle with the operating system, and reviewing a document about their software. They are usually hip with consistency and thus a good example, I thought.

In this case, they aren't entirely consistent. I found one case — in Accounts System Preferences while editing the Guest account — where they use both "log into" and "log in to," all on the same screen.

LeopardSystemPreferencesAccountsGuestEditLogin80.png

Drag and drop tabs in Safari

Frankly, I had utterly ignored drag and drop tabs in Safari. This feature didn’t work in older versions of the app and only appeared in Safari 3, so I hadn’t yet adjusted to it. The recent article on tag dragging modes at Daring Fireball comes about a week after my own interest in the feature suddenly piqued.

So, yes, drag and drop for tabs appeared relatively late in Safari’s development. I fail to use this feature even though I’ve wanted it for a long time. Together, these facts buttress my conviction that certain features need to be in a product on day one, or they will not get used. I refer to this as the “PageMaker window” problem, for it wasn’t until PageMaker 6-ish that you could open up more than one document at a time in PageMaker. By that time, I’d been using PageMaker for long enough that I had user interface scar tissue built up around the single-window limitation. Even though I had a feature I wanted, it was left unused most of the time.

Even if I did want to use tag drag and drop, its behavior in Safari is weird. I probably wouldn’t have taken the time to understand what was going on if it hadn’t been for the DF post. Or, at least, I wouldn’t have realized there were different modes at all. (It’s like user-interface-by-Zork-text-adventure. You have to discover the odd set of steps — which make some sense in hindsight — that drops the critical key from the keyhole onto the placement you’ve carefully slid under the door.)

My own experience with Safari 3 has shown that if the tab is the leftmost one in a Safari window, dragging it in any direction results in both the inter- and intra-window drag behavior described on DF. That’s the only tab position that works in this manner, though.

I also thought that holding down Option or Command during a drag would make a difference; I could swear that happened last week when I tried drag and drop, but I must be wrong. I can’t reproduce it today.

Update: There’s an older article at Betalogue that describes tab drag and drop, and mentions the behavior of the first tab.

Disabling an account in Mac OS X

Quite some time ago, I was involved in some work to figure out how to best disable an account in Mac OS X. It was a pretty interesting investigation.

In the end, we settled on two steps which worked for both admin and non-admin accounts:

  1. Set “*” as the account’s password.
  2. Add “;DisabledUser;” to the AuthenticationAuthority attribute for the user account in the local directory service.

Between the two — and I don’t recall whether both were strictly necessary — console logins were disabled, and remote logins were prevented from all of the sharing services that could be turned on in Sharing System Preferences.

When tested under Tiger, both of these were successfully cleared by the Reset Password Utility on the installer DVD. When the password was reset in this manner, the account was enabled for login.

While I haven’t replicated the results with Leopard, I have no reason to suspect a change (other than the adoption of DSLocal instead of NetInfo and the change to the DirectoryService superdaemon).

This is really handy information if, for example, you’d like to have a local admin account for emergencies but you want to force someone to explicitly enable it before use by booting from a system installer disc.

Update: It’s also important to remove any SSH keys that might allow logins to that account, if you want to fully disable access.

Global pwpolicy requires Password Server

Josh Wisenbaker posted to the MacEnterprise list, explaining that global policy for pwpolicy probably only works with the Password Server in Open Directory. It apparently does not work in the DSLocal local directory service (Leopard and greater) or NetInfo (Tiger and lower). You instead need per-user password policies at the local level.

This fits in with my recollection of password policy. I wrote my first Python system administration script to set password policy in Tiger. (Yes, I wrote a huge script to run a single shell command. Error checking! I blame error checking for the length! Plus, I hadn’t yet learned about a number of helpful modules that would have been nice to use.)

And in the end, writing it didn’t really buy me anything because, as I recall, the policies I set didn’t seem to apply globally. Plus, when I did get pwpolicy to apply to individual users, it only controlled normal user accounts and not admin accounts. But, if you’re okay with those limitations, you can loop through your local users and set pwpolicy on them.

Fwiw, I have a number of feature requests in about pwpolicy at the local level, and controlling it from a network directory service. I think you, too, should file requests about this.

Update: I am told it worked in Tiger but not in Leopard. Specifically, the passwords expire but there’s no opportunity to change them at loginwindow when that happens.

List the local user accounts whose UIDs are greater than 100

Here’s an example of how you can use the DirectoryService dscl utility to find which local user accounts have UIDs greater than 100. These users are by convention most likely to be non-system accounts, and therefore of interest for some tasks in a tool like Applejack. (I pulled this example from some comments in the Applejack 1.4.3 source.)

$ dscl /Local/Default -list /Users UniqueID | awk '$2 >= 100 { print $1; }'
supersecretadminaccount
christen
jeremy
elijah
demoguy

What’s going on in this example?

I’m getting a list of users from the default local DirectoryService node, whose path is /Local/Default. The output of this step gives you all of the local user accounts’ short usernames, followed by their UIDs, because that’s the property I was requesting. The data is arranged in two columns.

A drop into awk can make quick work of processing this columnar data, so I pipe the output of the first command in. Taking the output of dscl, I wanted to find whether the number in the second column was greater than or equal to 100, so I compare $2 to the desired number. When the UID column’s data matches, I print out only the short username from the first column, $1.

This gives you a list of usernames whose UIDs are greater than or equal to 100. The output is one per line, which is what you want if you have further processing steps.

“UniqueID” is the DirectoryService record type for UID. You could also use “uid” instead, and in this instance I’ve found that it works equally well.

$ dscl /Local/Default -list /Users uid | awk '$2 >= 100 { print $1; }'
supersecretadminaccount
christen
jeremy
elijah
demoguy

Substituting “uid” for “UniqueID” may not always work. It probably will in most cases, since the output is formatted similarly, but it depends on what subsequent processing steps are expecting. If those steps are splitting the columns/fields by whitespace, they should be fine either way.

$ dscl /Local/Default -read /Users/jeremy uid
dsAttrTypeNative:uid: 503
$ dscl /Local/Default -read /Users/jeremy UniqueID
UniqueID: 503

Another point of interest would be accounts greater than 500, as the Mac OS X Setup Assistant and Accounts System Preferences pane create local accounts starting with UIDs 501 by convention. Whether you choose greater than or greater than or equal to 500 is up to you. I’ve come across some situations where ID 500 gets used (somewhat unexpectedly), so you may want to find such UIDs or GIDs if it suits your purposes.

The difference between those accounts whose UIDs are greater than or equal to 100 and those greater than or equal to 500 would yield a list non-system accounts that are hidden by default from the login window or Accounts System Preferences pane. While you could generate two lists and compare with sort and uniq, you could just add to your awk statement.

$ dscl /Local/Default -list /Users UniqueID | awk '$2 >= 100 && $2 < 500 { print $1; }'

On most Mac OS X systems (as of this writing at least), there will be no accounts listed from the above statement. So, you’ll just get your command prompt back.

This should work in Tiger and Leopard, since dscl first became available in Tiger and replaced the NetInfo nicl utility entirely in Leopard.

Google Analytics plunge due to module change?

It looks like some recent change to the Google Analytics module for Drupal 5 broke my link to the Analytics service. Well, I’m being overbroad there. It really was working, but apparently only tracking when my administration account and users from a certain other user role (think: group) were logged in.

Well, obviously, that could lead to a significant traffic drop — if for no other reason than anonymous users weren’t being tracked — and that’s what I was seeing throughout my Analytics data. I only check Analytics every once in a while, and it’s currently only a curiosity to me, but it was still confusing as to why I saw all the graphs plunge starting March 7.

My best guess is that one of my recent module update binges loaded a new Google Analytics module which changed something, and only two user roles were set up to be tracked. (The Drupal 5 update process leaves something to be desired. Sure, I should have read the "read me" to find out about the change beforehand, but when you have so many modules to update, you just want to get it done. Wish it had warned me that something needed my attention.) Now that I’ve changed that setting and other user roles — including anonymous — will be tracked again, we’ll see what happens.

Save steps with the Mercurial fetch extension

The Mercurial fetch extension adds the hg fetch command. I’ve heard hg fetch described as “a great Do What I Mean kind of command.” It isn’t enabled by default, but it saves enough steps in the frequently-used push/pull-merge-commit cycle so many people turn it on when they set up Mercurial.

It seems as if the fetch extension is an open secret in the Hg community, but it took me some time to come across it so I thought I’d help raise its visibility. At least when I’m Googling my own site to remember something I’ve forgotten later.

Get the UUID for a Mac with ioreg

UUIDs, used throughout the rest of Mac OS X for identifying disks and users and groups and whatnot, have now become the unique identifier for ByHost preferences. Or so I’ve been informed, in this+article+on+the+topic+at+AFP548, which told me that Ethernet hardware addresses are no longer en vogue for this purpose in Leopard.

So, to get the UUID for your Mac you can do the following step suggested in the article:

$ ioreg -rd1 -c IOPlatformExpertDevice | grep -E '(UUID)'
"IOPlatformUUID" = "10703BFC-6664-40C5-9331-E73FCE2C2E29"

Let’s expand upon this for a moment. Switch that grepping over to awk, and you get:

$ ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { print $3; }'
"10703BFC-6664-40C5-9331-E73FCE2C2E29"

Note that you can strip the quotes in the same manner I did with serial numbers from ioreg:

$ ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { split($0, line, "\""); printf("%s\n", line[4]); }'
10703BFC-6664-40C5-9331-E73FCE2C2E29

Well, that’s it. I’m not going to launch into any long performance analysis of this … at least, not right now.

To get Mac serial numbers in scripts, is ioreg or system_profiler faster?

This is not your average post about how to get the serial number for your Mac from the command line or a script. Instead of showing how to do it, I’ll examine a few ways you might do it with via the provided UNIX shells, and compare how quickly they run.

There are two major ways I’m aware of to get the serial number of a Mac from the shell: the ioreg and system_profiler utilities. The output of either generally needs finessing to be useful — at the very least, you’ll want to narrow down the results to just the serial number if that’s all the data you need.

(However, if you need more data, don’t prematurely optimize for speed. Calling either tool multiple times without caching the results would likely result in a performance penalty. I would suspect this would get worse if you're calling one of the shell tools from within a Python or Perl script.)

Note that both shell tools require that your motherboard have a serial number assigned to it in order to show it to you. (You may not have this on a particular Mac if its motherboard has been repaired by replacement and your Apple Authorized Service Provider did not flash it with the serial number.) If you can’t see a Mac’s serial number in the “About this Mac” dialog box, you shouldn’t be able to read it with these other tools, either.

Let's start with the ioreg utility.

$ ioreg -l | awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s\n", line[4]); }'
W55512LPW3K

I realize you could get away without the printf statement but I kind-of like to make sure my output is formatted.

You could do the following, but it doesn’t return the raw serial number. Instead, the results are returned surrounded by quotes. (This is what I got off the MacEnterprise list, in a+post+by+Dennis+Lorenzen.

$ ioreg -l | awk '/IOPlatformSerialNumber/ { print $4; }'
"W55512LPW3K"

I found a negligible speed difference between various versions when I ran them with time, so stripping the quotes and using printf appeared to be reasonable. The extra processing arguably returns better output.

Most of the work appears to happen in ioreg. For example:

$ time ioreg -l | awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s\n", line[4]); }'
W55512LPW3K
ioreg -l 0.10s user 0.14s system 97% cpu 0.252 total
awk 0.01s user 0.00s system 5% cpu 0.250 total

You can get the same result with similar performance via system_profiler. I actually didn't expect that it would compare favorably, but it does. Here, I'll use another example posted in that MacEnterprise thread:

$ time system_profiler SPHardwareDataType | grep "Serial Number" | awk '{ print $3; }'
W55512LPW3K
system_profiler SPHardwareDataType 0.04s user 0.04s system 29% cpu 0.263 total
grep "Serial Number" 0.00s user 0.00s system 1% cpu 0.262 total
awk '{ print $3; }' 0.00s user 0.00s system 1% cpu 0.260 total

But if you optimize a bit to eliminate the grep step — because it is superfluous if you're already calling awk — you do get the fastest results I’ve come across. It's worth noting that they have been variable results, especially but not always between the first time and subsequent runs. So, I wouldn't be surprised if there was some other caching or other mechanism at work that helps make speed this method along.

$ time system_profiler SPHardwareDataType | awk '/Serial Number/ { print $3; }'
W55512LPW3K
system_profiler SPHardwareDataType 0.04s user 0.04s system 51% cpu 0.156 total
awk '/Serial Number/ { print $3; }' 0.00s user 0.00s system 2% cpu 0.155 total

Credit goes to the discussion of this topic on the MacEnterprise mailing list, but if you Google for the topic you’ll find a lot of hits and helpful information. I did a little bit of extra editing in awk to strip the quote marks and time the execution for the ioreg version. I’m also happy I did the timing so that I know that the system_profiler route does appear to be the quickest in overall execution and low in CPU usage.

Syndicate content