Determine OS X keyboard layout ("input source") in the terminal/a script?

Recently I had written a small console utility (https://github.com/myshov/xkbswitch-macosx) on Objective-C to do this. It's a lot faster than a script based solutions. It can to get the current input layout but also it can to set the given input layout.

To get a current layout:

$xkbswitch -ge
> US

To set a given layout:

$xkbswith -se Russian

Note: @MarkSetchell deserves credit for coming up with the fundamental approach - where to [start to] look and what tools to use. After further investigation and back and forth in the comments I thought I'd summarize the solution (as of OS X 10.9.1):

do shell script "defaults read ~/Library/Preferences/com.apple.HIToolbox.plist \\
 AppleSelectedInputSources | \\
 egrep -w 'KeyboardLayout Name' | sed -E 's/^.+ = \"?([^\"]+)\"?;$/\\1/'"

Note how \ is escaped as \\ for the benefit of AppleScript, which ensures that just \ reaches the shell. If you want to execute the same command directly from the shell (as one line), it would be:
defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources | egrep -w 'KeyboardLayout Name' |sed -E 's/^.+ = \"?([^\"]+)\"?;$/\1/'

  • The currently selected keyboard layout is stored in the user-level file ~/Library/Preferences/com.apple.HIToolbox.plist, top-level key AppleSelectedInputSources, subkey KeyboardLayout Name.
  • defaults read ensures that the current settings are read (sadly, as of OSX 10.9, the otherwise superior /usr/libexec/PlistBuddy sees only a cached version, which may be out of sync).
  • Since defaults read cannot return an individual key's value, the value of interest must be extracted via egrep and sed - one caveat there is that defaults read conditionally uses double quotes around key names and string values, depending on whether they are a single word (without punctuation) or not.

Update:

Turns out that AppleScript itself can parse property lists, but it's a bit like pulling teeth. Also, incredibly, the potentially-not-fully-current-values problem also affects AppleScript's parsing.

Below is an AppleScript handler that gets the current keyboard layout; it uses a do shell script-based workaround to ensure that the plist file is current, but otherwise uses AppleScript's property-list features, via the Property List Suite of application System Events.

Note: Obviously, the above shell-based approach is much shorter in this case, but the code below demonstrates general techniques for working with property lists.

# Example call.
set activeKbdLayout to my getActiveKeyboardLayout() # ->, e.g., "U.S."

on getActiveKeyboardLayout()
  
  # Surprisingly, using POSIX-style paths (even with '~') works with 
  # the `property list file` type.
  set plistPath to "~/Library/Preferences/com.apple.HIToolbox.plist"
  
  # !! First, ensure that the plist cache is flushed and that the
  # !! *.plist file contains the current value; simply executing
  # !! `default read` against the file - even with a dummy
  # !! key - does that.
  try
    do shell script "defaults read " & plistPath & " dummy"
  end try
  
  tell application "System Events"
    
    repeat with pli in property list items of ¬
      property list item "AppleSelectedInputSources" of ¬
      property list file plistPath
      # Look for (first) entry with key "KeyboardLayout Name" and return
      # its value.
      # Note: Not all entries may have a 'KeyboardLayout Name' key, 
      # so we must ignore errors.
      try
        return value of property list item "KeyboardLayout Name" of pli
      end try
    end repeat
    
  end tell
end getActiveKeyboardLayout

I am not sure of this answer, but it may be worth checking out. If you look in file:

/Library/Preferences/com.apple.HIToolbox.plist

there is a variable called

AppleCurrentKeyboardLayoutSourceID

and mine is set to "British" and I am in Britain...

You can read the file in a script with:

defaults read /Library/Preferences/com.apple.HIToolbox.plist  AppleEnabledInputSources

sample output below:

(
    {
    InputSourceKind = "Keyboard Layout";
    "KeyboardLayout ID" = 2;
    "KeyboardLayout Name" = British;
}
)

So, I guess your question can be simply answered using this:

#!/bin/bash
defaults read /Library/Preferences/com.apple.HIToolbox.plist  AppleEnabledInputSources | grep -sq Swedish
[[ $? -eq 0 ]] && echo Swedish

This question led to the creation of the keyboardSwitcher CLI Tool: https://github.com/Lutzifer/keyboardSwitcher

Though similar to the already mentioned https://github.com/myshov/xkbswitch-macosx this has additional features, e.g. the list of Layouts is not hardcoded and thus can also support third party layouts (e.g. Logitech) and supports installation via homebrew.