Bash Script: Enable Access to Assistive Devices Programmatically in OS X Mavericks 10.9.x - Simulate Keystrokes
Using a bash script to enable access to assistive devices is possible in Mavericks (and also Yosemite) despite the move to a per-app database. This is useful for entering keystrokes or clicking GUI buttons via a bash script.
Prior to OS X Mavericks, enabling access to assistive devices was relatively easy. Running the command
sudo touch /private/var/db/.AccessibilityAPIEnabled
would enable it. But now each app now needs to be allowed or disallowed access.
I often used Applescript/osascript to simulate keystrokes or click GUI buttons, which was great for automating “un-scriptable” tasks on multiple computers. One particular feature I always found incredibly useful was logging a user in via the
loginwindow by sending it a script from a remote machine. This proved useful in a lab environment when I wanted to open a specialized piece of software to make sure it worked on all of the machines.
The script would simulate keystrokes and fill in the username and password fields and then press enter or click login. Unfortunately, Mavericks does not allow Applescript (or more accurately,
/usr/bin/osascript ) by default, which is what I used to accomplish this from my script. Trying to run this script returned an error:
62:115: execution error: System Events got an error: osascript is not allowed assistive access. (-10006)
The first thing I tried was to drag
/usr/bin/osascript into the Accessibility window of the Security & Privacy Preferences pane, which is how you can add other apps. This did not work as the command-line tool was not an .app .
Needless to say, after struggling to figure out how to enable this through a script, I finally found a way.
Enable Access To Assistive Devices via bash
Each entry in the Accessibility window is actually part of a database file. Using sqlite3 , this file can be manipulated to add, remove, or modify items. To get
osascript to work at the login window and be allowed access to assistive devices, run this command:
If you are using
sudo tccutil.py -i com.apple.RemoteDesktopAgent
Or you can use
sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "INSERT or REPLACE INTO access VALUES('kTCCServiceAccessibility','com.apple.RemoteDesktopAgent',1,1,1,NULL)"
To remove it:
sudo tccutil.py -r com.apple.RemoteDesktopAgentsudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "DELETE from access where client='com.apple.RemoteDesktopAgent'"
or completely wipe out every entry with:
tccutil reset Accessibility
osascript must be some part of
/System/Library/CoreServices/RemoteManagement/ARDAgent.app, because another script I was working on triggered the prompt to allow it access.
After enabling it in System Preferences and rebooting,
I was able to run the script I have used for years that enters a users credentials into the login window fields via a script sent from Apple Remote Desktop. The script is below, but I also have multiple versions of it on my Github page. Even one written in Python.
osascript -e <<EOF 'tell application "System Events" tell process "SecurityAgent" set value of text field 2 of window "Login" to "username" set value of text field 1 of window "Login" to "password" end tell tell application "system events" to keystroke return tell application "system events" to keystroke return end tell' EOF
When enabling this, I also add a few other things that may come in useful:
sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "INSERT or REPLACE INTO access VALUES('kTCCServiceAccessibility','com.apple.LockScreen',1,1,1,NULL)" sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "INSERT or REPLACE INTO access VALUES('kTCCServiceAccessibility','com.apple.systemevents',1,1,1,NULL)" sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "INSERT or REPLACE INTO access VALUES('kTCCServiceAccessibility','/usr/bin/say',1,1,1,NULL)" sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db "INSERT or REPLACE INTO access VALUES('kTCCServiceAccessibility','/usr/bin/osascript',1,1,1,NULL)" This allows me to use things like the lock screen or the
This allows me to use things like the lock screen or the say command from the login window. In my scripts, I use it as a visual indicator that the job is done without having to log in. I can either listen for the command to complete or the lock screen to disappear.
tccutil only supports one command in Mavericks. I wrote my own version of it called tccutil.py. You can get it below, or look at the source code.
This is just a little Python command line utility that can be used in scripts. I’m sure Apple will expand their utility, but for now, this is something you can use.
Scripting Your Own GUI Actions
If you want to automate mouse clicks or keystrokes, I would suggest using UIElementInspector, or Accessibility Inspector, as it is called now (part of Xcode). This works great to find out what window, menu, or button names are called, so you can use them in your AppleScripts or bash scripts (
If you are using Mavericks, you will have to--ironically--allow it access to accessibility by either dropping it in the list, or following the prompts when you run the app for the first time.
osascript to the accessibility database doesn’t always mean your app or script will run without producing the error. Often, you need to add the app that is being manipulated. For example, if you had an AppleScript that clicked a menu in TextEdit, you would need to add TextEdit to the accessibility database.