6

I have this line:

trap 'jobs -p | xargs kill -9' SIGINT SIGTERM EXIT

it is repeated in many bash shell scripts I have.

What is the best way to share this code? Can I call a bash function perhaps?

In reality, I am creating a framework and the user will be expected to write some glue shell scripts. What would be nice if the user's shell scripts could inherit from a base shell script, somehow. Or they could just call bash functions that pre-exist somehow.

The problem is that if I create a bash function like so:

// a.sh
function trap_and_kill_child_jobs {
    trap 'jobs -p | xargs kill -9' SIGINT SIGTERM EXIT
}

and call it from another script like so:

// b.sh
source ./a.sh
trap_and_kill_child_jobs
sh -c 'sleep 10000 &' &   # I want this process to be killed by `trap_and_kill_child_jobs`
./run-some-tests.js

the caller script (b.sh) does not actually experience the trap. The 'child jobs' created by b.sh will continue running.

13
  • 1
    "What would be nice if the user's shell scripts could inherit from a base shell script, somehow." Please don't use shell for this. It's not really a language. It IS for glue scripts, and nothing else. Every shell scripting "framework" I've seen (without exception) is (a) complex, (b) buggy, (c) a nightmare for the poor sap who gets to inherit and attempt to maintain it.
    – Wildcard
    Commented Sep 6, 2017 at 4:23
  • Yeah I hear ya, this is just for putting one shell script in between stuff, I doubt very many poor saps will be sapped. Commented Sep 6, 2017 at 4:34
  • @Wildcard can you speak to why calling the trap_and_kill_child_jobs function wouldn't invoke trap to actually work? Commented Sep 6, 2017 at 19:44
  • Without seeing the rest of your script, no, I can't. You don't show any child jobs being created.
    – Wildcard
    Commented Sep 6, 2017 at 19:51
  • 1
    Thanks. You need to get into the details of how node works. I'm not a JS developer, but I expect what's going on is that node is forking and starting some other processes, and then exiting. So it won't show up in your "jobs" list at all. Again, a shell scripting framework is almost invariably code smell. You have architectural problems here; you're trying to use the shell to keep track of internal workings of JS when it really can't do that.
    – Wildcard
    Commented Sep 6, 2017 at 20:12

1 Answer 1

4

It would be enough create a script file that contain your framework functions like this:

/tmp/framework.sh

# Define a serie of functions of your framework...
function framework_function_1() {
    echo "function 1 executed"
}

function framework_function_2() {
    echo "function 2 executed"  
}

# And put here anything you want to be executed right away (like the trap)
echo "framework.sh was executed"

Then include it in the rest of your scripts like this:

/tmp/b.sh

# Include the framework:
.  /tmp/framework.sh

echo "Script b.sh was executed"
# Calling a framework's function
framework_function_2

With this the execution of b.sh (and any other script including framework.sh) will be like:

$ /tmp/b.sh 
framework.sh was executed
Script b.sh was executed
function 2 executed

Note that . /tmp/framework.sh is the same as source /tmp/framework.sh.

2
  • yeah for some reason when I call trap_and_kill_child_jobs from b.sh it doesn't actually work..maybe you can try my example and see if it works? Commented Sep 6, 2017 at 19:45
  • It will work if you change your trap to: trap 'kill -9 $(jobs -p)' SIGINT SIGTERM EXIT Commented Sep 6, 2017 at 22:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .