[KSH/Bash] Starting a parent process from a child process?

Hey all, I need to launch a script from within 2 other scripts that can run independently of the two parent scripts... Im having a hard time doing this, if anyone knows how please let me know.

More detail.

ScriptA (bash), ScriptB (ksh), ScriptC (bash)

ScriptA, launches ScriptB
ScirptB, launchs ScriptC

From ScriptC.. I need to kill ScriptA and ScriptB make some changes.. then luanch ScriptA again.

So Im trying to luanch ScriptC from ScriptB like so:

/tmp/ScriptC >> /tmp/log.log 2>&1 &
disown %1

That's not working because when I kill ScriptA and ScriptB... ScriptC gets a term signal and bails out. What am I missing here?

Start the scripts in background and with "nohup". see the man page of "nohup" for details.

If you start them this they will no longer stop when the parent process is killed. This mechanism was originally for making sure a process would be persistent even if its terminal process got killed (hence the name: "no [termination upon] h[ang]up").

Btw., it might be a clever idea to control the processes in question with a PID file in such an environment: when starting them create a temporary file with the PID in it, which can be used to kill the process. This file will also be indicative of a process be running or not.

I hope this helps.

bakunin

Thanks bakunin, Ill give nohup a shot. :slight_smile:

That probably won't help, unless the controlling terminal is lost or a SIGHUP is being sent with kill. I assume that he's using either ^C (SIGINT) at the keyboard or a typical kill command (SIGTERM); nohup will not prevent a process from receiving either of these.

Your pid file suggestion is a good one though. Something along the lines of:

$ cat a.sh
#!/bin/sh

echo $$ > a.pid
./b.sh &
#Do whatever script a is supposed to do


$ cat b.sh
#!/bin/sh

echo $$ > b.pid
./c.sh &
# Do whatever script b is supposed to do


$ cat c.sh
#!/bin/sh

# Do whatever script c is suposed to do
kill $(cat a.pid b.pid)
# Make needed changes
./a.sh &

Although any external executables running asynchronously at the time that the parent shell receives SIGTERM from kill will linger until they're done. If that's an issue, then a.sh would need to be started asynchronously and any signals sent to its process group (which b, c, a, b ... and further iterations in the cycle would inherit).

Regards,
Alister

Hmm, he said that he starts scriptA, which starts scriptB, which in turn starts scriptC and scriptC should kill A and B without being killed itself - exactly this is what nohup can do for him, no?

bakunin

The death of a process, even a parent process, does not trigger the kernel to send SIGHUP to any processes. That only happens when the controlling terminal/pseudo terminal is hung up/closed. If SIGHUP is not the signal being sent, nohup will not prevent a process dying if that is the default action for whatever signal it is actually being sent (a SIGINT or SIGTERM will still kill a process, unless they're explicitly trapped by the receiving process).

Default behavior when a SIGHUP signal is sent to a process is for the kernel to terminate the process. nohup simply sets the SIGHUP signal to be ignored and then execs its argument (the command you want to run, which then inherits this signal handling modification from nohup ... all other singal handling is unmodified).

The heart of OpenBSD's nohup implementation:

	/*
	 * The nohup utility shall take the standard action for all signals
	 * except that SIGHUP shall be ignored.
	 */
	(void)signal(SIGHUP, SIG_IGN);

	execvp(argv[1], &argv[1]);

from src/usr.bin/nohup/nohup.c - view - 1.14

Regards,
Alister

OK, now i understand, where you come from. We misunderstood each other, because we were talking about different things. In ksh it is standard that SIGHUP is sent to any child process in background once the father process gets killed. If script A calls script B by a line like "b.sh &" B will be terminated once A is killed. (I believe this is a main difference to the BASH shell, which handles the case differently.) Using a line like "nohup b.sh &" would prevent B from being killed if A is terminated.

Yes, this behavior is not necessarily the same for processes in general, as you have correctly pointed out. In (Korn) shell programming and for processes created by the ksh this is the case though.

bakunin

That's a good point, though not the complete story. ksh only sends SIGHUP to its children when it is a login shell and it itself has been sent a SIGHUP. A ksh script started with "#!/bin/ksh" is not a login shell.

Note: In bash, any interactive shell (login or not) will propagate a received SIGHUP (again, though, most scripts are not run from interactive shells).

Cheers,
Alister