Skip to main content
Jamf Nation, hosted by Jamf, is the largest Apple IT management community in the world. Dialog with your fellow IT professionals, gain insight about Apple device deployments, share best practices and bounce ideas off each other. Join the conversation.
CCA Badge CCE Badge CUG Badge Integrator Badge
15

Terminal Notifier commands hanging

Posted: 6/18/13 at 3:01 AM by bentoms

Hi There,

I have a re-wrapped version of Terminal Notifier that i wish to use to notify end user of policies etc..

I have a collection of scripts that work locally as the user as when as root from the terminal (via su).

But they seem to either hang or fail with a syntax error when run by Casper. Any pointers? Examples below:

#!/bin/sh

loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`

if [[ $loggedInUser != root ]]; then

    echo "User $loggedInUser is logged in..."

    # Display alert to the user
    su "$loggedInUser" -c `/usr/local/bin/Company\ Alerts.app/Contents/MacOS/terminal-notifier -title "Updates Are Awaiting Install" -message "These updates will be installed when you next logout, restart or shutdown" -groupid updates`

else 

    echo "No User logged in..."   


fi
15
CCA Badge CCE Badge CUG Badge Integrator Badge

Posted: 6/18/13 at 3:38 AM by bentoms

This example will hang:

#!/bin/sh
loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`

if [[ $loggedInUser != root ]]; then

    echo "User $loggedInUser is logged in..."

    # Display alert to the user
    sudo -u "$loggedInUser" /usr/local/bin/Company\ Alerts.app/Contents/MacOS/terminal-notifier -message "These updates will be installed when you next logout, restart or shutdown" -title "Updates Are Awaiting Install" -groupid updates

else 

    echo "No User logged in..."   


fi
CCA Badge CCE Badge CUG Badge Integrator Badge

Posted: 6/18/13 at 3:45 AM by bentoms

hmm.. so does this...

#!/bin/sh
loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`

if [[ $loggedInUser != root ]]; then

    echo "User $loggedInUser is logged in..."

    # Display alert to the user
    su -c `/usr/local/bin/Company\ Alerts.app/Contents/MacOS/terminal-notifier -message "These updates will be installed when you next logout, restart or shutdown" -title "Updates Are Awaiting Install" -groupid updates` -s /bin/sh "$loggedInUser"
else 

    echo "No User logged in..."   


fi
CCA Badge CCE Badge CUG Badge Integrator Badge

SOLVED Posted: 6/18/13 at 11:32 AM by bentoms

Looks like it's a known issue https://github.com/alloy/terminal-notifier/issues/29

CCA Badge

Posted: 6/18/13 at 11:54 AM by mm2270

Ben, the only effective way I've ever been able to get Terminal Notifier to work 100% of the time is with the use of a LaunchAgent to call it up. Thee issue has more to do with the additional sandboxing in Lion and now more so with Mountain Lion that anything else. Apparently attempting to display a Notification Center message not AS the logged in user will get blocked or fail.

CCA Badge CJA Badge

Posted: 6/18/13 at 1:27 PM by Josh_S

Give this a shot.

#!/bin/sh

loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`
if [[ $loggedInUser != root ]]; then
    echo "User $loggedInUser is logged in..."
    # Get the PID of Dock.app
    loggedInPID=$(ps -axj | awk "/^$loggedInUser/ && /Dock.app/ {print \$2;exit}")
    # Display alert to the user
    launchctl bsexec "${loggedInPID}" sudo -iu "${loggedInUser}" "/usr/local/bin/Company\\ Alerts.app/Contents/MacOS/terminal-notifier -message \"These updates will be installed when you next logout, restart or shutdown\" -title \"Updates Are Awaiting Install\" -groupid updates"
else 
    echo "No User logged in..."
fi
CCA Badge CCE Badge CUG Badge Integrator Badge

Posted: 6/18/13 at 3:29 PM by bentoms

Thanks Josh, i'll give that a go..

Looks like i could've done with that bit of information some months ago https://github.com/alloy/terminal-notifier/issues/44 might have been what i was missing.

The bonus of cocoaDialog is that i can set the notifications to be persistent with little effort.

CCA Badge

Posted: 6/19/13 at 12:07 PM by mm2270

@Josh_S,

Thanks for posting your version of a script for this. I'm very interested in getting terminal-notifier to work with a regular script downloaded from the JSS and not using the LaunchAgent method I came up. I tried out your script and unfortuantely it seems the only way it has worked is if the terminal-notifier app is in a path WITHOUT spaces. Any time its located in a path with spaces, no matter what I've tried, it fails, claiming no such file or directory. I've tried setting up the path as a variable and placing it later in the script with quotes, without quotes, curly bracing it, quoting AND curly bracing it and finally just putting the path directly in the script line with spaces escaped. None of these have worked. it still fails every time saying it doesn't exist. I'm at a loss. Usually one of the above methods gets around space issues, but not this time. Must be something with the bsexec function that I just don't understand.

Here is what the policy log states (only the relevant error lines):

-bash: /Library/Application: No such file or directory
launchctl bsexec failed: No such file or directory

Using other paths with spaces and other methods of escaping all yield the same type of error.

Any thoughts?

CCA Badge CJA Badge

Posted: 6/19/13 at 12:17 PM by Josh_S

I forgot to test in a path that included a space. Try double-escaping the space. I just got the following to work.

launchctl bsexec "${loggedInPID}" sudo -iu "${loggedInUser}" "/Library/Application\\ Support/JAMF/terminal-notifier -message \"These updates will be installed when you next logout, restart or shutdown\" -title \"Updates Are Awaiting Install\" -groupid updates"

I really hate working with spaces in scripts for this very reason. You could also create a temporary, or permanent, symbolic link to the terminal-notifier command that doesn't include spaces.

ln -s /Library/Application\ Support/JAMF/terminal-notifier /tmp/terminal-notifier
# The rest of the script
rm /tmp/terminal-notifier
CCA Badge

Posted: 6/19/13 at 1:53 PM by mm2270

@ Josh,

Thanks for the quick response and help on this. Been playing with it, and I figured out what I was doing wrong. Your tips helped, but it actually turned out to be my ignorance in how the script was actually telling terminal-notifier to do its thing.

See, I didn't realize that the whole line after the sudo -iu including the path to terminal-notifier was one command enclosed in quotes being passed in. I was attempting to use variables for the -title and -message rather than being hardcoded in, among other things, so it can be flexible. I mistakenly did not enclose the line in quotes, but I had the variables for title and message quoted. It was getting tripped up somewhere along there because of that. Once I understood that, I was able to make the necessary adjustments without needing to double escape the path to the app or use a symlink.

Sp thanks. So far testing is going well! Seems to be working like a charm via policy and I can assign parameters for the title, message, use -active (or -open) and a click-back action. Sweet!

CCA Badge CJA Badge CMA Badge

Posted: 10/21/13 at 3:55 PM by tron_jones

Solved

Ended up trying Josh's line and Bens link and found that I had the syntax wrong. Was using \"$4"\ instead of the correct \"$4\"

@ mm2270
Mind sharing the quoting part for the parameters to work. I have everything working in shell but am having the same problem with the syntax for the parameters to work in a policy or with remote.

launchctl bsexec "${loggedInPID}" sudo -iu "${loggedInUser}" "/Library/Application\\ Support/JAMF/terminal-notifier/terminal-notifier.app/Contents/MacOS/terminal-notifier" -message '$4' -sound 'default' -title '$5' -execute '$6'

Posted: 3/2/16 at 7:39 AM by jmb03012

@Josh_S

I have a similar issue, I ended up using asuser for my 10.10 and 10.11 machines, but I'm having problems getting bsexec to work for my 10.9 and older.

Initially I was getting

/bin/launchctl bsexec "${LoggedInPID}" sudo -iu "${LoggedInUser}" "/bin/launchctl load /Library/LaunchAgents/com.bloomberg.BNotifier.plist"
sudo: unable to execute /bin/bash: Bad address
launchctl bsexec failed: No such file or directory

Then I thought OK, I didnt need to escape out the spaces on launchctl and load with asuser but maybe I need to here so I ran

/bin/launchctl bsexec "${LoggedInPID}" sudo -iu "${LoggedInUser}" "/bin/launchctl\ load\ /Library/LaunchAgents/com.bloomberg.BNotifier.plist"
-bash: /bin/launchctl load /Library/LaunchAgents/com.bloomberg.BNotifier.plist: No such file or directory
launchctl bsexec failed: No such file or directory

Similar but slightly different error.

Any thoughts?

UPDATE:
So I do have the syntax correct, I've noticed that if I run the command several times it eventually works, usually on the second or third run so I think sytax is good, but I cant explain why it doesnt consistently work (when it does fail it gets the same error as above).

Posted: 6/27/16 at 3:08 PM by May

Hi @jmb03012 did you ever resolve this ?

I'm having intermittent success loading a LaunchAgent from a script run as root

sudo: unable to execute /bin/bash: Bad address launchctl bsexec failed: No such file or directory

i'm using

/bin/launchctl bsexec "${loggedInPID}" sudo -iu "${loggedInUser}" "launchctl load /Library/LaunchAgents/local.adpassmon.job.plist"

sometimes it loads the agent but most of the time it wont.

CCA Badge

Posted: 6/27/16 at 3:22 PM by mm2270

@May What OS? The launchctl bsexec command no longer works with El Capitan and only marginally worked under Yosemite. The Bad address error is often the result of it running on 10.10.
You should now use launchctl asuser as mentioned on this thread: https://jamfnation.jamfsoftware.com/discussion.html?id=9902
Look toward the end of the thread for the solution.

Posted: 6/27/16 at 3:34 PM by May

Thanks @mm2270

It's failing on 10.9, though i need it to work on 10.9 to 10.11, looking into asuser now, thank you.

We'll have some 10.9 machines around for a little while so i'll use @jmb03012 approach from here

Posted: 6/28/16 at 9:18 AM by jmb03012

@May we ended up doing a form of the below, in the case of this specific example its a preinstall script that is in the installer/upgrade package.

#!/bin/sh
## preinstall

#Jordan Bender, Bloomberg LP, 2016
#Version 1.16

#Checks if <myapp> is installed on the machine, and if so unloads the LaunchAgent, and then removes existing <myapp> components

###Variables###
OSVersion=$(sw_vers | grep ProductVersion)
Label=com.bloomberg.<myapp>
LoggedInUser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
LoggedInUID=$(id -u $LoggedInUser)
LoggedInPID=$(ps -axj | awk "/^$LoggedInUser/ && /Dock.app/ {print \$2;exit}")

###Paths###
<myapp>=/Library/Application\ Support/Bloomberg/<myapp>/<myapp>.app
<myapp>LaunchAgent=/Library/LaunchAgents/com.bloomberg.<myapp>.plist

###Functions###
#This section intentionally left blank

###Script Contents - Do Not Modify Below This Line###

case $OSVersion in

*10.[6-9]*)
if [[ -d "$<myapp>" ]]; then
echo "<myapp> is installed, unloading LaunchAgent and removing existing version"
Count=1
/bin/launchctl bsexec "$LoggedInPID" /usr/bin/sudo -iu "$LoggedInUser" "/bin/launchctl unload \"$<myapp>LaunchAgent\" &> /dev/null"
while [[ `echo $?` != 0 ]] && [[ "$Count" -lt 20 ]]
do
/bin/launchctl bsexec "$LoggedInPID" /usr/bin/sudo -iu "$LoggedInUser" "/bin/launchctl unload \"$<myapp>LaunchAgent\" &> /dev/null"
((Count++))
done
if /usr/bin/sudo /bin/launchctl list "$Label" &> /dev/null; then
/usr/bin/sudo /bin/launchctl unload "$<myapp>LaunchAgent"
fi
/usr/bin/sudo rm -rf "$<myapp>"
/usr/bin/sudo rm -f "$<myapp>LaunchAgent"
echo "Existing <myapp> version has been removed"
else
echo "<myapp> is not installed, no preinstall actions taken"
fi
;;

*10.[10-11]*)
if [[ -d "$<myapp>" ]]; then
echo "<myapp> is installed, unloading LaunchAgent and removing existing version"
Count=1
/bin/launchctl asuser "$LoggedInUID" /usr/bin/sudo -iu "$LoggedInUser" "/bin/launchctl unload \"$<myapp>LaunchAgent\" &> /dev/null"
while [[ `echo $?` != 0 ]] && [[ "$Count" -lt 20 ]]
do
/bin/launchctl asuser "$LoggedInUID" /usr/bin/sudo -iu "$LoggedInUser" "/bin/launchctl unload \"$<myapp>LaunchAgent\" &> /dev/null"
((Count++))
done
if /usr/bin/sudo /bin/launchctl list "$Label" &> /dev/null; then
/usr/bin/sudo /bin/launchctl unload "$<myapp>LaunchAgent"
fi
/usr/bin/sudo rm -rf "$<myapp>"
/usr/bin/sudo rm -f "$<myapp>LaunchAgent"
echo "Existing <myapp> version has been removed"
else
echo "<myapp> is not installed, no preinstall actions taken"
fi
;;

esac