If you simply want to launch a Mac application (*.app
) asynchronously,
- use
open -a
with the bundle directory path (ending in .app
)
- and pass any pass-through command-line arguments after
--args
(see man open
):
sudo -u $USER_NAME open -a /usr/local/TestApp/Test.app --args -l
See note at the bottom re reliably determining $USER_NAME
, the invoking user's username.
If, for some reason, you do need to target the executable embedded in the *.app
bundle directly, you must use Bash's &
control operator to run the command in the background:
#!/bin/bash
# Get the underlying username (see comments below).
userName="${HOME##*/}"
# Launch the app in the background, using control operator `&`
# which prevents the command from blocking.
# (Given that the installer runs the script as the root user,
# `sudo` is only needed here for impersonation.)
sudo -u "$userName" /usr/local/TestApp/Test.app/Contents/MacOS/Test -l &
# Load the daemon.
# (Given that the installer runs the script as the root user,
# `sudo` is not needed here.)
launchctl load /Library/LaunchDaemons/com.testapp.plist
Note that I've changed the way that the underlying username is determined:
${HOME##*/}
extracts the last path component from $HOME
, the underlying user's home directory path, which reflects the user who invoked the installer.
This is more robust than using who
without arguments, whose output can include other users.
(As an aside, who | head -1 | head -1 | awk '{print $1;}'
can be simplified to the more efficient who | awk '{print $1; exit}
).