Skip to main content

I would like to create a launchdaemon that launch a script when finder and dock processes are existing.  I don´t know if anyone has something similar running they can try and show . 

the launchdaemon I can create on my own - but how to build in script that it only should run if those dock and finder process exist I struggle to find

Yeah, this is possible to do. But before I go into how I'm doing this in one of my scripts, I was wondering if what you're trying to run in the LaunchDaemon has to be run as root. If it doesn't need root, then the perhaps easier way to handle this would be to use a LaunchAgent, which by nature, will only run when someone is logged in, meaning there's no need to check for the Dock and/or Finder running.

If what you have to do does need a LaunchDaemon, then here's some code that could work to drop into your script. The basic idea is, you keep looping in the script until the conditions that Dock and Finder are both found as active processes. Once you break out of the loop, the rest of your script can continue.

#!/bin/zsh

dock_process=$(/usr/bin/pgrep -l "Dock")
finder_process=$(/usr/bin/pgrep -l "Finder")
until [[ "$dock_process" && "$finder_process" ]]; do
/bin/sleep 1
done

echo "Dock and Finder are both running"

 


Ok thansen 

ok great. Will give it a try if i Can get This built Into a launchdeamon - and yes it must run as root but first when the user see the 2 processes


Something i do wrong as this does not work

#!/bin/zsh

dock_process=$(/usr/bin/pgrep -l "Dock")
finder_process=$(/usr/bin/pgrep -l "Finder")
until [[ "$dock_process" && "$finder_process" ]]; do
/usr/local/jamf/bin/jamf policy
done

echo "Dock and Finder are both running"

And another additional question:

I created the  launchdaemon as pkg and placed it in pre-stage. The plist file is there, but it is not loaded when getting into the desktop first time the user sees it ... how to solve that


A LaunchDaemon will not load automatically after being installed until its loaded by a command or a restart happens.

Since I'm guessing you'd rather avoid restarting for this, you can use launchctl to load the LaunchDaemon. There's more than one way to do this, syntax-wise. I still have luck using a command like this.

/bin/launchctl load /Library/LaunchDaemons/nameOfLaunchDaemon.plist

This also should work I think, and is often referred to as the more up to date syntax to use.

/bin/launchctl bootstrap system/<service-name>

As for the until loop not working, are you adding that into a script being called by your LaunchDaemon? Because the above script syntax can't be easily added into the ProgramArguments of a LaunchDaemon itself.

Try adding one of those kinds of commands to whatever it is that's deploying your LaunchDaemon to get it loaded right after it installs. If needed, you might need to add a postinstall script


@jameson, below is a script that I use to create a luanch daemon for me and launch DEPNotify after enrollment. It should be able to help with your situation as well. I've commented out as much as I could, just let me know if you need help understanding something.

#!/bin/bash

# Create and load a LaunchDaemon to delay depnotify launch

echo "<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.depnotify</string> # Launch Damon name
<key>UserName</key> # Use this to specify a username
<string>root</string> # Here we are specifying the root user
<key>ProgramArguments</key>
<array>
<string>/usr/local/jamf/bin/jamf</string> # This is the path to the jamf binary. I like to keep my scripts in the cloud so lines 15-18 are summoning my custom script policy.
<string>policy</string>
<string>-event</string>
<string>jamfSetup</string>
<string>-randomDelaySeconds</string>
<string>25</string>
</array>
<key>RunAtLoad</key> # Run this daemon at load
<true/>
<key>StartInterval</key> # I want this to run every 10 seconds so I've added a Start Interval. The interger below is 10 for "10 Seconds"
<integer>10</integer>
</dict>
</plist>" > /tmp/depnotify.plist

sudo chown root:wheel /tmp/depnotify.plist
sudo chmod 755 /tmp/depnotify.plist
sudo launchctl load /tmp/depnotify.plist

exit 0

So this is what you use in pre-stage, so right after the user see the desktop first time it should initiate depnotify ?


@Captainamerica Yeah, It basically kicks off a chain of events. This launc hdaemon is deployed at enrollment, then kicks off my wait script, which waits until the desktop & dock are loaded. That script then initiates the depnotify GUI from the cloud. This would be much faster if I did it locally though. I just like the ability to edit quickly with the could.


Where in the script is stated that desktop and dock is loaded before anything is kicked in ? - May just be my scripting skills that is missing, as I also have been tried to find a solution for similar


@jameson If you look at the Launch Daemon I've created, You'll see that the script isn't visible because I'm calling it with a policy that I've set up in Jamf Pro "sudo jamf policy -event jamfSetup" It's  just formatted differently in XML.

<string>/usr/local/jamf/bin/jamf</string>
<string>policy</string>
<string>-event</string>
<string>jamfSetup</string>

 

 


@jameson If you look at the Launch Daemon I've created, You'll see that the script isn't visible because I'm calling it with a policy that I've set up in Jamf Pro "sudo jamf policy -event jamfSetup" It's  just formatted differently in XML.

<string>/usr/local/jamf/bin/jamf</string>
<string>policy</string>
<string>-event</string>
<string>jamfSetup</string>

 

 


The script below is the one being called by the Launch Daemon from my "jamfSetup" policy.

 

#!/bin/bash

# Determine the current user

currentUSER=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name && ! /loginwindow/ { print $3 }' )

jamfBinary=/usr/local/jamf/bin/jamf

# Determine if currentUser is logged in

if pgrep -x "Finder" \\
&& pgrep -x "Dock" \\
&& [ "$currentUSER" != "_mbsetupuser" ]; then

# Declare currentUser is logged in

echo "$currentUser is now logged in."

# Kill any installer process running

killall Installer

# Wait a few seconds

sleep 2

# Run the DEPNotify Starter Script

$jamfBinary policy -event launchWizard

# Unload depnotify.plist

sudo launchctl unload /tmp/depnotify.plist

else

echo "The requirements above have not been met."

fi

exit 0
exit 1

 


So the below script, how do you execute that in pre-stage ?.  Should I just add in in a pkg and add a postscript script inside this pkg or how ?

 

#!/bin/bash

# Create and load a LaunchDaemon to delay depnotify launch

echo "<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.depnotify</string> # Launch Damon name
<key>UserName</key> # Use this to specify a username
<string>root</string> # Here we are specifying the root user
<key>ProgramArguments</key>
<array>
<string>/usr/local/jamf/bin/jamf</string> # This is the path to the jamf binary. I like to keep my scripts in the cloud so lines 15-18 are summoning my custom script policy.
<string>policy</string>
<string>-event</string>
<string>jamfSetup</string>
<string>-randomDelaySeconds</string>
<string>25</string>
</array>
<key>RunAtLoad</key> # Run this daemon at load
<true/>
<key>StartInterval</key> # I want this to run every 10 seconds so I've added a Start Interval. The interger below is 10 for "10 Seconds"
<integer>10</integer>
</dict>
</plist>" > /tmp/depnotify.plist

sudo chown root:wheel /tmp/depnotify.plist
sudo chmod 755 /tmp/depnotify.plist
sudo launchctl load /tmp/depnotify.plist

exit 0

 


OK - did a little troubleshooting. 

So the launchdaemon on client is running  after pre-stage (can also see the depnotifyplist in /tmp) and should trigger event "jamfSetup" 
But this for some reason does not seem to happen. If I go to terminal manually and do a sudo jamf policy -event jamfSetup the flow is working. 
So something does not seem to kick right in ?


It seems the launchdaemon is not loaded correctly. If I do a sudo launchctl list com.depnotify is show on status "78" 

we looked up status 78 which mean "function not implemented"  So something in pre-stage package scripts seems to be not working, since it cannot load. Even tried a restart of the machine, but still the same status appear 


It seems the launchdaemon is not loaded correctly. If I do a sudo launchctl list com.depnotify is show on status "78" 

we looked up status 78 which mean "function not implemented"  So something in pre-stage package scripts seems to be not working, since it cannot load. Even tried a restart of the machine, but still the same status appear 


Download code Runner and test loading the daemon first. Then upload it to your server once you've verified that it works. I suggest removing the comments from the daemon. I usually don't run it with those comments.


Download code Runner and test loading the daemon first. Then upload it to your server once you've verified that it works. I suggest removing the comments from the daemon. I usually don't run it with those comments.


#!/bin/bash

# Create and load a LaunchDaemon to delay depnotify launch

echo "<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.ACME.depnotify</string>
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/jamf/bin/jamf</string>
<string>policy</string>
<string>-event</string>
<string>jamfSetup</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>4</integer>
</dict>
</plist>" > /tmp/depnotify.plist

sudo chown root:wheel /tmp/depnotify.plist
sudo chmod 755 /tmp/depnotify.plist
sudo launchctl unload /tmp/depnotify.plist
sudo launchctl load /tmp/depnotify.plist

exit 0

Code is working fine in coderunner

The Pkg I create If I run this on a normal machine, the Launchdaemon is loaded as it should

If I take same package into pre-stage the issue happens. Launchdaemon somehow does not manage to load propably and keep status 78.
Is there any special trick to get a launchdaemon pkg loaded during pre-stage ? - the package works outside pre-stage and yes package is signed, as else the deamon plist would also not appear


Hmmm...I'm not packaging my daemon script. I have a policy in Jamf Pro that triggers it at enrollment.


also remove the "unload" near the bottom of the script. That is for Code Runner testing only.


Yeah I know, that the script you posted does write the launchdaemon - but tried also to just create it as pkg, to see if that changes anything. But overall the either as your script or to create a PKG with a postinstall script that load the launchdaemon should give the same result.



Yeah I know, that the script you posted does write the launchdaemon - but tried also to just create it as pkg, to see if that changes anything. But overall the either as your script or to create a PKG with a postinstall script that load the launchdaemon should give the same result.



Trying running it with an enrollment trigger without packaging it and see what happens. We can continue troubleshooting from there.


Overall the issue is not enrollment trigger, but that the launchdaemon created is not running. So no matter what I put in there is not executed - not even if I try to do a restart afterwards the launchdaemon is not loaded by the system


but if I do a manually launchdaemon load of the depnotify.plist it works


Sounds like it wants you to run as the logged in user then.


and of course if I try to manually install the package on a mac is also working. But if I install same package in pre-stage, the launchdaemon is not loaded, unless I do a manual load


Reply