ulimit -t 1 limits the script's CPU time to 1 second. When the script has consumed all its CPU time it gets killed.
To limit the CPU time of just one command in your script you can use parentheses to start it in a subshell with its own limit, e.g.
(ulimit -t 1; LD_PRELOAD=../../EasySandbox/EasySandbox.so ./a.out < $testin)
Answer from Florian Diesch on askubuntu.comEnable core dump in your system, it is the most commonly used method for app crash analysis. I know it is a bit painful to gdb core file, but more or less you can find something out of it. Here is a reference link for you.(http://www.cyberciti.biz/tips/linux-core-dumps.html).
Another way to do this is tracing you script by "strace -p PID-X", note that it will slow down your system, espeically several hours in your case, but it can be the last resort.
Hope above helpful to you.
Better to check all the signals generated and caught by OS at that time by specific script might be one of signal is causing to kill your process.
To improve, use killall, and also combine the commands:
ps -aux | grep script_name
killall script_name inotifywait
Or do everything in one line:
killall `ps -aux | grep script_name | grep -v grep | awk '{ print $1 }'` && killall inotifywait
List the background jobs using
# jobs
Then choose the the prior number of job and run
example
# fg 1

will bring to foreground.
Then kill it using CTRL+C or easier way to find the PID of script using
ps -aux | grep script_name

Then kill using pid
sudo kill -9 pid_number_here
I would do something like this:
#!/bin/bash
trap : SIGTERM SIGINT
echo $$
find / >/dev/null 2>&1 &
FIND_PID=$!
wait $FIND_PID
if [[ $? -gt 128 ]]
then
kill $FIND_PID
fi
Some explanation is in order, I guess. Out the gate, we need to change some of the default signal handling. : is a no-op command, since passing an empty string causes the shell to ignore the signal instead of doing something about it (the opposite of what we want to do).
Then, the find command is run in the background (from the script's perspective) and we call the wait builtin for it to finish. Since we gave a real command to trap above, when a signal is handled, wait will exit with a status greater than 128. If the process waited for completes, wait will return the exit status of that process.
Last, if the wait returns that error status, we want to kill the child process. Luckily we saved its PID. The advantage of this approach is that you can log some error message or otherwise identify that a signal caused the script to exit.
As others have mentioned, putting kill -- -$$ as your argument to trap is another option if you don't care about leaving any information around post-exit.
For trap to work the way you want, you do need to pair it up with wait - the bash man page says "If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes." wait is the way around this hiccup.
You can extend it to more child processes if you want, as well. I didn't really exhaustively test this one out, but it seems to work here.
$ ./test-k.sh &
[1] 12810
12810
$ kill 12810
$ ps -ef | grep find
$
Was looking for an elegant solution to this issue and found the following solution elsewhere.
trap 'kill -HUP 0' EXIT
My own man pages say nothing about what 0 means, but from digging around, it seems to mean the current process group. Since the script get's it's own process group, this ends up sending SIGHUP to all the script's children, foreground and background.
The process your cmd is supposed to be run in will be killed by the SIGHUP signal between the fork() and the exec(), and any nohup wrapper or other stuff will have no chance to run and have any effect. (You can check that with strace)
Instead of nohup, you should set SIGHUP to SIG_IGN (ignore) in the parent shell before executing your background command; if a signal handler is set to "ignore" or "default", that disposition will be inherited through fork() and exec(). Example:
#! /bin/sh
trap '' HUP # ignore SIGHUP
xclock &
trap - HUP # back to default
Or:
#! /bin/sh
(trap '' HUP; xclock &)
If you run this script with xfce4-terminal -H -x script.sh, the background command (xclock &) will not be killed by the SIGHUP sent when script.sh terminates.
When a session leader (a process that "owns" the controlling terminal, script.sh in your case) terminates, the kernel will send a SIGHUP to all processes from its foreground process group; but set -m will enable job control and commands started with & will be put in a background process group, and they won't signaled by SIGHUP.
If job control is not enabled (the default for a non-interactive script), commands started with & will be run in the same foreground process group, and the "background" mode will be faked by redirecting their input from /dev/null and letting them ignore SIGINT and SIGQUIT.
Processes started this way from a script which once run as a foreground job but which has already exited won't be signaled with SIGHUP either, since their process group (inherited from their dead parent) is no longer the foreground one on the terminal.
Extra notes:
The "hold mode" seems to be different between xterm and xfce4-terminal (and probably other vte-based terminals). While the former will keep the master side of the pty open, the latter will tear it off after the program run with -e or -x has exited, causing any write to the slave side to fail with EIO. xterm will also ignore WM_DELETE_WINDOW messages (ie it won't close) while there are still processes from the foreground process group running.
I have been playing with this. I can't figure it out, but here is what I have discovered. I used sleep 3 as my cmd.
These two work. I have no idea what the ls at the end does. The brackets and double nohup, well they make a sub-process (I think that is how nohup works). I have no idea why nohup on its own does not work.
#!/bin/bash
nohup nohup sleep 3 &
ls #no idea why I need this
and
#!/bin/bash
(
nohup sleep 3 &
ls #no idea why I need this
)
/bin/true works in place of ls. Seems like we need to call an external command. Still no idea why.
Every process has to have a parent process (to collect exit status, at the very least). see man 2 wait. If a parent process dies, its children are sent a SIGHUP signal (see man 7 signal). SIGHUP is a catchable signal, but if the child doesn't catch it, the default action is to kill the child process.
See man nohup to keep things going.
To execute a background job and keep it running after terminal is closed use:
nohup command &>/dev/null &
A few things that may cause a shell to exit (not exhaustive):
- calling the
exitutility. Let's not forget about the obvious - calling the
returnutility. In the case ofbashthat will return only if in a function or sourced file. exec cmd. That will executecmdin the same process so in effect breaking out of that loop. The script will end whencmdexits.set -e/set -o errexitis enabled (see also theSHELLOPTSenvironment variable forbash) and a command exits with an error.set -u/set -o nounsetis enabled and an unset variable is referenced.- a
DEBUGorERRtrap is defined that callsexit. - Failing special builtins. Failure of special builtins (like
set,:,eval...) causes the shell to exit. In the case ofbashthough, that only happens in POSIX mode (like when POSIXLY_CORRECT is in the environment or when invoked assh...) and even then not for all special builtins. For instance: > /will cause the shell to exit. - as mentioned by @schily, syntax error (like in code that is only reached conditionally).
- division by 0 (in
$((1/x))or${array[1/x]}). - internal
basherror for instance because some limit is reached:- fails to allocate memory
- fails to fork a process
- stack size exceeded (for instance when using function recursion)
- Some other limits in place via
ulimit(which may also cause some signals to be sent).
- killed by a another process. Another process can call
kill()to explicitly kill the interpreter of your script. - killed by the system.
- SIGINT/SIGQUIT. If you press
^C/^\. - SIGHUP. If the terminal is disconnected.
- SIGSEGV/SIGBUS/SIGILL. The bash command does something wrong (a bug) or failing hardware (memory).
- SIGPIPE: builtin (
echo,printf) writing to a now-closed pipe or socket (could also happen for error messages if stderr is a pipe).
- SIGINT/SIGQUIT. If you press
The first thing to check would be the error messages and the exit status.
A syntax error in a script will terminate the script.
If your script code includes shell variables that may include spaces in some cases, this may cause a syntax error in case the shell variable is not enclosed in double quotes.
You haven't written a script in your example; it's a function. You're therefore applying the kill to your interactive shell session. Interactive shells ignore most signals, including the SIGTERM that you're sending.
Put the function and its call in a script and run that. It's far more likely to do what you expect.
try following, if you want to use it as function directly in bash, respectively sourced from console.
function testKill
{
kill $PPID
echo "no hello :-/"
}
Depends on the signal. Bash allows you to trap with the trap command, but if your script is being killed with SIGKILL (9), it is uninterruptible and untrappable.
It sounds like this may be a case for some sort of watchdog process similar to how keepalived tracks processes.
At the simplest, the command pidof might be your friend here.
A process isn't "killed with SIGHUP" -- at least, not in the strict sense of the word. Rather, when the connection is dropped, the terminal's controlling process (in this case, Bash) is sent a hang-up signal*, which is commonly abbreviated the "HUP signal", or just SIGHUP.
Now, when a process receives a signal, it can handle it any way it wants**. The default for most signals (including HUP) is to exit immediately. However, the program is free to ignore the signal instead, or even to run some kind of signal handler function.
Bash chooses the last option. Its HUP signal handler checks to see if the "huponexit" option is true, and if so, sends SIGHUP to each of its child processes. Only once its finished with that does Bash exit.
Likewise, each child process is free to do whatever it wants when it receives the signal: leave it set to the default (i.e. die immediately), ignore it, or run a signal handler.
Nohup only changes the default action for the child process to "ignore". Once the child process is running, however, it's free change its own response to the signal.
This, I think, is why some programs die even though you ran them with nohup:
- Nohup sets the default action to "ignore".
- The program needs to do some kind of cleanup when it exits, so it installs a SIGHUP handler, incidentally overwriting the "ignore" flag.
- When the SIGHUP arrives, the handler runs, cleaning up the program's data files (or whatever needed to be done) and exits the program.
- The user doesn't know or care about the handler or cleanup, and just sees that the program exited despite nohup.
This is where "disown" comes in. A process that's been disowned by Bash is never sent the HUP signal, regardless of the huponexit option. So even if the program sets up its own signal handler, the signal is never actually sent, so the handler never runs. Note, however, that if the program tries to display some text to a user that's logged out, it will cause an I/O error, which could cause the program to exit anyway.
* And, yes, before you ask, the "hang-up" terminology is left over from UNIX's dialup mainframe days.
** Most signals, anyway. SIGKILL, for instance, always causes the program to terminate immediately, period.
Points 1-4 are correct. I know nothing about point 5. As for your final point, a fine application, screen, will allow you to let all processes run to their natural end, regardless of how you terminate your connection. Screen is in the repos.
The man description of screen is not easy to read, but, among other things, it states:
When screen is called, it creates a single window with a shell in it (or the specified command) and then gets out of your way so that you can use the program as you normally would. Then, at any time, you can create new (full-screen) windows with other programs in them (including more shells), kill existing windows, view a list of windows, turn output logging on and off, copy-and-paste text between windows, view the scrollback history, switch between windows in whatever manner you wish, etc. All windows run their programs completely independent of each other. Programs continue to run when their window is currently not visible and even when the whole screen session is detached from the user's terminal.
When a program terminates, screen (per default) kills the window that contained it. If this window was in the foreground, the display switches to the previous window; if none are left, screen exits.
I have highlighted the most important part: you can detach the window with the command Ctrl+a+d, and then you may kill/logout your session, and the now-detached window will continue to live, with the programs inside still running. When you connect back, for instance by initiating a new ssh session, the command screen -r will resume the screen session which had been detached earlier, with all output to standard error/output clearly visible.
I was able to test the prctl idea I posted about in a comment and it seems to work. You will need to compile this:
#include "sys/prctl.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
int main(int argc, char ** argv){
prctl(PR_SET_PDEATHSIG, atoi(argv[1]),0,0,0);
char * argv0 = strdup(argv[2]);
char * slashptr = strrchr(argv0, '/');
if(slashptr){
argv0 = slashptr + 1;
}
return execvp(argv0, &(argv[2]));
}
Let's say you have compiled the above to an executable named "prun" and it is in your path. Let's say your script is called "foo.sh" and it is also in your path. Make a wrapper script that calls
prun 15 foo.sh
foo.sh should get SIGTERM when the wrapper script is terminated for any reason, even SIGKILL.
Note: this is a linux only solution and the c source code presented is without detailed checking of arguments
Thanks to Mux for the lead. It appears that there is no way to do this in bash except for manually catching signals. Here is a final working (overly commented) version.
trap : SIGTERM SIGINT # Trap these two (killing) signals. These will cause wait
# to return a value greater than 128 immediately after received.
mplayer "$vid" & # Start in background (PID gets put in `$!`)
pid=$!
wait $pid # Wait for mplayer to finish.
[ $? -gt 128 ] && { kill $pid ; exit 128; } ; # If a signal was recieved
# kill mplayer and exit.
Refrences: - traps: http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html