1

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.

  • 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 Sep 6 '17 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. – Alexander Mills Sep 6 '17 at 4:34
  • @Wildcard can you speak to why calling the trap_and_kill_child_jobs function wouldn't invoke trap to actually work? – Alexander Mills Sep 6 '17 at 19:44
  • Without seeing the rest of your script, no, I can't. You don't show any child jobs being created. – Wildcard Sep 6 '17 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 Sep 6 '17 at 20:12
3

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.

  • 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? – Alexander Mills Sep 6 '17 at 19:45
  • It will work if you change your trap to: trap 'kill -9 $(jobs -p)' SIGINT SIGTERM EXIT – WPomier Sep 6 '17 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.