When can a script fork a background process?

lww3
New Contributor

Please consider the following Script, delivered as the sole payload of a Policy "_DEV LWW Test:"

#!/bin/bash
sh -c 'sleep 300; echo good > /tmp/ok' &

There are plenty of other Jamf Community posts (here's one and another one) which offer use-cases and success stories which involve forking a process to the background. Jamf Pro; Install & Upgrade methods for macOS Catalina is a particularly relevant thread for us. The Script above is a stripped-down, abstract version of a larger Script related to software updates.

I have configured the Policy to trigger upon "Recurring check-in" and with Execution Frequency = "Ongoing." As shown in the attached picture, I see different results based on how the Policy and its Script are invoked:

  • Automatically on the 15-minute check-in timer: The script runs without error (according to jamf.log and the Logs in the Jamf Pro web interface) but there is no sh -c sleep 300 process left running in the background.
  • Manually via jamf policy: The script runs without error and an sh process is left running in the background.
  • By launching the Policy from Self Service: The script runs without error and an sh process is left running in the background.

Can someone help me to understand the difference between the first bullet and the latter two? Is this reproducible on other systems, or maybe it is localized to our own — in which case it may be a product of security software? I'd really appreciate a hint as to where to look next.

Attached picture, with colored bars to represent commands run around the same time:

DifferentJamfLaunches.png

1 ACCEPTED SOLUTION

arminBriegel
New Contributor III
New Contributor III

Not sure what the difference between the three methods is, but your problem is that you are backgrounding the process but not disinheriting it. The '&' operator sends a process to the background, but it is still considered a child process of the spawning process, which in your case is the shell that runs the script code from Jamf. when the parent process terminates, the child process is terminated as well.

To fully spawn an independent, long-running process, you need to use `nohup` as well as `&`. However, depending on the use case, I would recommend setting up and loading a launch daemon or agent instead. It'll be more reliable.

 

View solution in original post

5 REPLIES 5

arminBriegel
New Contributor III
New Contributor III

Not sure what the difference between the three methods is, but your problem is that you are backgrounding the process but not disinheriting it. The '&' operator sends a process to the background, but it is still considered a child process of the spawning process, which in your case is the shell that runs the script code from Jamf. when the parent process terminates, the child process is terminated as well.

To fully spawn an independent, long-running process, you need to use `nohup` as well as `&`. However, depending on the use case, I would recommend setting up and loading a launch daemon or agent instead. It'll be more reliable.

 

Thank you very much! For some reason, nohup didn't work directly for me, and instead produces the following error in nohup.log: "nohup: can't detach from console: Undefined error: 0"

This may very well be something wrong in our environment. This (old) StackOverflow answer suggests that PAM may affect the ability of a process to detach from its terminal. At the very least, it opens the possibility that some methods of establishing a shell (su versus ssh versus tmux whatever jamf policy does) might behave differently from others.

In any case, your suggestion to use a launch daemon was spot-on and worked for me! Searching the Jamf community for the keyword "nohup" led to a convenient sample script here: "Unexpected behavior in script running on auto checkin versus via 'sudo jamf policy'"

sdagley
Esteemed Contributor II

@lww3 I see you found my post on using `jamf scheduleTask`. While it is one way to create & schedule a LaunchDaemon you'd be better off creating a LaunchDaemon independent of Jamf Pro. 

lww3
New Contributor

Thank you for clarifying that point, @sdagley . I had been wondering about that myself, given that the jamf scheduledTask verb is only listed when running jamf help -hidden

Is the scheduledTask verb deprecated? Or does creating a LaunchDaemon simply give us more flexibility?

sdagley
Esteemed Contributor II

@lww3 It may end up being deprecated in the future, so better to not depend on the Jamf binary to be your vehicle for creating a LaunchDaemon. And you definitely have more flexibility when creating your own LaunchDaemons. And if you have haven't found them already, here are a couple of good resources for dealing with LaunchDaemons:

https://www.launchd.info 

https://zerolaunched.herokuapp.com