Posted on 06-18-2013 01:01 AM
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
Solved! Go to Solution.
Posted on 06-18-2013 09:32 AM
Looks like it's a known issue https://github.com/alloy/terminal-notifier/issues/29
Posted on 06-18-2013 01:38 AM
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
Posted on 06-18-2013 01:45 AM
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
Posted on 06-18-2013 09:32 AM
Looks like it's a known issue https://github.com/alloy/terminal-notifier/issues/29
Posted on 06-18-2013 09:54 AM
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.
Posted on 06-18-2013 11:27 AM
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
Posted on 06-18-2013 01:29 PM
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.
Posted on 06-19-2013 10:07 AM
@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?
Posted on 06-19-2013 10:17 AM
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
Posted on 06-19-2013 11:53 AM
@ 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!
Posted on 10-21-2013 01:55 PM
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 on 03-02-2016 05:39 AM
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 on 06-27-2016 01:08 PM
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.
Posted on 06-27-2016 01:22 PM
@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 on 06-27-2016 01:34 PM
Posted on 06-28-2016 07:18 AM
@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