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 .
$ 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
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.