The Bridge Between the Terminal and the GUI
macOS is built on a Unix foundation, which means the Terminal can interact with almost any underlying system file. However, there is historically a strict boundary between command-line operations and graphical user interface (GUI) actions. If you write a bash script in the Terminal, it cannot natively click a button in Safari, display a graphical pop-up window, or tell Apple Music to skip to the next track.
To cross this boundary, Apple created AppleScript—an English-like scripting language designed specifically to control graphical macOS applications.
The osascript (Open Scripting Architecture Script) command is the magical tool that bridges the gap. It allows you to execute AppleScript code directly from the Terminal or embed GUI-controlling code directly inside a standard bash script.
Step 1: Running a One-Line AppleScript
The simplest way to use osascript is with the -e (execute) flag, which allows you to pass a single line of AppleScript directly into the Terminal without needing to create a dedicated file.
For example, if you want your bash script to display a standard macOS graphical pop-up alert when it finishes running, you can inject this command:
osascript -e 'display dialog "The server backup is complete!" buttons {"OK"} default button "OK"'
When you press Enter, the Terminal will pause, and a native graphical dialog box will appear in the center of your screen. The Terminal will wait for you to physically click “OK” before it returns to the prompt.
Step 2: Controlling Applications
You can use osascript to send commands directly to running applications. This is incredibly useful for creating custom keyboard shortcuts or automating your workflow.
To force the Apple Music app to pause the current song from the command line, use:
osascript -e 'tell application "Music" to pause'
To tell Safari to completely quit (rather than forcefully killing the process with killall, which can cause data loss), use:
osascript -e 'tell application "Safari" to quit'
This asks the application to shut down gracefully, exactly as if you had pressed Command+Q on the keyboard.
Step 3: Executing Multi-Line Scripts
If your AppleScript is long and complex (for example, a script that opens Mail, creates a new message, attaches a specific file, and clicks send), passing it as a single line with the -e flag becomes a nightmare of quotation marks and escape characters.
Instead, you should open the Script Editor app (found in Applications > Utilities) and write your AppleScript normally. Save the file with the .scpt extension (e.g., SendReport.scpt).
You can then use the Terminal to execute that saved file simply by passing the filepath to osascript:
osascript /Users/yourusername/Documents/SendReport.scpt
Step 4: Interacting with JavaScript for Automation (JXA)
While AppleScript is powerful, its English-like syntax can be frustrating for modern developers who are used to standard programming languages.
macOS actually supports JavaScript for Automation (JXA). You can use the osascript command to execute JavaScript code to control the graphical interface by adding the -l JavaScript (language) flag.
To display an alert using JavaScript instead of AppleScript:
osascript -l JavaScript -e 'var app = Application.currentApplication(); app.includeStandardAdditions = true; app.displayAlert("Hello from JavaScript");'
By mastering osascript, you can create hybrid workflows that combine the raw, automated power of bash with the rich, graphical interactivity of the macOS desktop.