3

According to a trick from this question is-there-a-way-to-write-a-bash-function-which-aborts-the-whole-execution...

My example code (example.sh):

trap "exit 0" TERM
top_pid=$$

evalInput(){

    cmd=$1

    if [[ $cmd =~ ^\ *exit\ *$ ]]; then
        kill -s TERM $top_pid
    elif [another command]
        ...
    fi
}

If I type evalInput "exit" then this process will be killed with exit status zero.

Test file:

testExitCmd(){
    . ./example.sh
    ...
    evalInput "exit"
    ps [PID of `evalInput` function]
    # `ps` command is failed if evalInput is killed. 
    assertNotEquals "0" "$?"
}

. shunit2

My idea to test evalInput function is very simple, just use ps command to make sure that evalInput function is killed but the problem is how I can done this? The important issue here is when you try to execute evalInput that mean you also kill testExitCmd function.

I've tried many ways already e.g. using & to put evalInput to another process and bla bla bla. but I still get an error like shunit2:WARN trapped and now handling the (TERM) signal. As I understand, this indecate that I try to kill my test function process.

Please carefully test it, I don't think just only your imagination can solve this problem but please test a code. If you are on OSX you can simply install shUnit2 via brew and simply run it by ./your_test_script.sh

Alex Harvey
  • 14,494
  • 5
  • 61
  • 97
fronthem
  • 4,011
  • 8
  • 34
  • 55

2 Answers2

1
trap "exit 0" TERM
top_pid=$$

evalInput(){

    cmd=$1
    echo "CMD: $cmd"

    if [[ $cmd =~ ^\ *exit\ *$ ]]; then
        kill -s TERM $top_pid
    fi
}

testExitCmd(){
    evalInput "exit" &
    echo "Test evalInput"
    ps [PID of `evalInput` function]
    # `ps` command is failed if evalInput is killed. 
    assertNotEquals "0" "$?"
}

testExitCmd

Output

 Test evalInput
 CMD: exit

Does that help at all?

doktoroblivion
  • 428
  • 3
  • 14
1

Let's me ans my own question, I found some tricky way, the procedure is

  1. Spawn target program as child process and put it to a background,
  2. Run child process then stop it for 1 second,
  3. In parent process, save PID of child process to file tmp,
  4. Child process is awake then read PID from tmp to $top_pid,
  5. The child process now knows its PID, then running a kill command should be work.

My example code (example.sh):

trap "exit 0" TERM
top_pid=$$

evalInput(){

    cmd=$1

    if [[ $cmd =~ ^\ *exit\ *$ ]]; then
        kill -s TERM $top_pid
    elif [another command]
        ...
    fi
}

If I type evalInput "exit" then this process will be killed with exit status zero.

Test file:

testExitCmd(){
    (
        . ./example.sh
        sleep 1 # 1) wait for parent process save PID to file `temp`
        top_pid=`cat tmp` # 4) save PID to `top_pid`
        evalInput "exit" # 5) kill itself
    )&
    echo "$!" > tmp # 2) save PID of background process to file `tmp`
    sleep 2 # 3) wait for child process kill itself
    child_pid=$!
    ps $child_pid # `ps` command is failed if evalInput is killed. 
    assertNotEquals "0" "$?"
}

. shunit2
fronthem
  • 4,011
  • 8
  • 34
  • 55