Execute a shell function with timeout

timeout is a command - so it is executing in a subprocess of your bash shell. Therefore it has no access to your functions defined in your current shell.

The command timeout is given is executed as a subprocess of timeout - a grand-child process of your shell.

You might be confused because echo is both a shell built-in and a separate command.

What you can do is put your function in it's own script file, chmod it to be executable, then execute it with timeout.

Alternatively fork, executing your function in a sub-shell - and in the original process, monitor the progress, killing the subprocess if it takes too long.


There's an inline alternative also launching a subprocess of bash shell:


timeout 10s bash <<EOT
function echoFooBar {
  echo foo
}

echoFooBar
sleep 20
EOT


You can create a function which would allow you to do the same as timeout but also for other functions:

function run_cmd { 
    cmd="$1"; timeout="$2";
    grep -qP '^\d+$' <<< $timeout || timeout=10

    ( 
        eval "$cmd" &
        child=$!
        trap -- "" SIGTERM 
        (       
                sleep $timeout
                kill $child 2> /dev/null 
        ) &     
        wait $child
    )
}

And could run as below:

run_cmd "echoFooBar" 10

Note: The solution came from one of my questions: Elegant solution to implement timeout for bash commands and functions


As Douglas Leeder said you need a separate process for timeout to signal to. Workaround by exporting function to subshells and running subshell manually.

export -f echoFooBar
timeout 10s bash -c echoFooBar