简体   繁体   中英

Kill background processes in Linux

I'm trying to build a start script and a stop script for my project. I need to run a sass auto-compiler as well as a server, and redirect the output of both to a file. I'm using lite-server and sass --watch for this.

To make these processes run concurrently, I'm using & to background the processes. This poses the challenge of stopping the scripts, I can't stop the scripts using Ctrl+C as I normally would. I thought I would overcome this by storing the process IDs in a text file.

I came up with the following "start" script:

# Start a sass watcher and a server running simultaneously. Store the PIDs in a
# text file so that the processes can be easily stopped.

(
  lite-server &
  echo $! > .pids.txt &
  sass --watch sass:css --style=compressed &
  echo $! >> .pids.txt &
) &> log.txt
cat .pids.txt

Then, to stop the processes, I'm using

kill $(cat .pids.txt)

Writing the process IDs to a text file seems kind of hackish. Is there a better way to accomplish what I'm trying to do?

I may prefer to grep for the process and kill the process instead keeping the PIDs in a file.

ps -ef | grep lite-server | awk '{print $2}' | kill -9

I assume second column in output of ps -ef is PID of the process lite-server in your server.

您应该添加您想要的“杀死”类型..例如: kill -9 $(cat .pids.txt)

You could store them in an array, if that's what you wouldn't call hackish.

EDIT: Another way is to just execute:

kill $(jobs -p)

This kills all background processes (jobs -p prints the PIDs of all background process to stdout, which are then handed to kill).

I found Run multiple commands and kill them as one in bash , and the more detailed How to Create a Process Group in Linux and Kill All Its Children .

In short:

$ setsid sh -c 'command1 & command2 & command3 & wait'
$ process_group_id=$!
$
$ # and/or save to a file like '.pgid'
$ echo $process_group_id > .pgid
$
$ # to kill everything in that process group (mind the dash):
$
$ kill -TERM -$process_group_id

Note

Killing with kill $process_group_id will NOT kill the entire group! There must be a preceding - when killing an entire process group by id.

Also, you should pass the appropriate signal using kill . To print all the signals, run:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

So a forced kill would be:

$ kill -9 -$process_group_id
$ # OR
$ kill -SIGKILL -$process_group_id

But if the commands have a way of handling SIGTERM :

$ kill -15 -$process_group_id
$ # OR
$ kill -TERM -$process_group_id
$ # OR
$ kill -SIGTERM -$process_group_id

There is more in kill: Send a signal to processes if you are using GNU coreutils . If not, maybe man kill or info kill could help better.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM