Shell functionality start-stop-restart script

I'm a shell newbie trying to figure out some kind of code, but there are a few lines that are too complicated for me. The part of the code I'm talking about can be found here: https://gist.github.com/447191 It is designed to start, stop and restart the server. This is pretty standard material, so it’s worth taking some time to figure it out. I commented on these lines where I am not sure about the meaning or that I do not completely understand, hoping that someone can give me some explanation.

#!/bin/bash # BASE=/tmp PID=$BASE/app.pid LOG=$BASE/app.log ERROR=$BASE/app-error.log PORT=11211 LISTEN_IP='0.0.0.0' MEM_SIZE=4 CMD='memcached' # Does this mean, that the COMMAND variable can adopt different values, depending on # what is entered as parameter? "memcached" is chosen by default, port, ip address and # memory size are options, but what is -v? COMMAND="$CMD -p $PORT -l $LISTEN_IP -m $MEM_SIZE -v" USR=user status() { echo echo "==== Status" if [ -f $PID ] then echo echo "Pid file: $( cat $PID ) [$PID]" echo # ps -ef: Display uid, pid, parent pid, recent CPU usage, process start time, # controling tty, elapsed CPU usage, and the associated command of all other processes # that are owned by other users. # The rest of this line I don't understand, especially grep -v grep ps -ef | grep -v grep | grep $( cat $PID ) else echo echo "No Pid file" fi } start() { if [ -f $PID ] then echo echo "Already started. PID: [$( cat $PID )]" else echo "==== Start" # Lock file that indicates that no 2nd instance should be started touch $PID # COMMAND is called as background process and ignores SIGHUP signal, writes it's # output to the LOG file. if nohup $COMMAND >>$LOG 2>&1 & # The pid of the last background is saved in the PID file then echo $! >$PID echo "Done." echo "$(date '+%Y-%m-%d %X'): START" >>$LOG else echo "Error... " /bin/rm $PID fi fi } # I don't understand this function :-( kill_cmd() { SIGNAL=""; MSG="Killing " while true do LIST=`ps -ef | grep -v grep | grep $CMD | grep -w $USR | awk '{print $2}'` if [ "$LIST" ] then echo; echo "$MSG $LIST" ; echo echo $LIST | xargs kill $SIGNAL # Why this sleep command? sleep 2 SIGNAL="-9" ; MSG="Killing $SIGNAL" if [ -f $PID ] then /bin/rm $PID fi else echo; echo "All killed..." ; echo break fi done } stop() { echo "==== Stop" if [ -f $PID ] then if kill $( cat $PID ) then echo "Done." echo "$(date '+%Y-%m-%d %X'): STOP" >>$LOG fi /bin/rm $PID kill_cmd else echo "No pid file. Already stopped?" fi } case "$1" in 'start') start ;; 'stop') stop ;; 'restart') stop ; echo "Sleeping..."; sleep 1 ; start ;; 'status') status ;; *) echo echo "Usage: $0 { start | stop | restart | status }" echo exit 1 ;; esac exit 0 
+4
source share
2 answers

1) COMMAND="$CMD -p $PORT -l $LISTEN_IP -m $MEM_SIZE -v" - -v in the Unix tradition, it is often a shortcut for --verbose . All these dollar signs are variable extensions (their text values ​​are inserted into the string assigned to the new COMMAND variable).

2) ps -ef | grep -v grep | grep $( cat $PID ) ps -ef | grep -v grep | grep $( cat $PID ) ps -ef | grep -v grep | grep $( cat $PID ) is pipe: ps redirects its output to grep, which outputs to another grep, and the final result is printed to standard output. grep -v grep means "accept all lines that do not contain" grep "(grep itself is a process, so you need to exclude it from ps output). $( $command ) is a way to run a command and paste its standard output into it the location of the script (in this case: cat $PID displays the contents of a file named $ PID).

3) kill_cmd . This function is an endless loop trying to kill the LIST of memcached PID modules. Firstly, he tries to send a TERM signal (politely asking each process in $ LIST to exit, save his work and close it correctly), gives them 2 seconds ( sleep 2 ) to complete the job, and then he tries to make sure that all processes are destroyed using the KILL signal ( -9 ), which immediately terminates the process using the capabilities of the OS: if the process has not completed operation within 2 seconds, it is considered to be freezing). If slaying with kill -9 was successful, it deletes the PID file and terminates the loop.

ps -ef | grep -v grep | grep $CMD | grep -w $USR | awk '{print $2}' ps -ef | grep -v grep | grep $CMD | grep -w $USR | awk '{print $2}' prints all PIDs of processes with the name $ CMD ('memcached') and the user $ USR ('user'). -w option grep means "full word only" (this excludes situations when the searched name is part of another process name, for example "fakememcached"). awk is a small interpreter that is most often used to enter the word number N from each input line (you can think of it as a selector for a text table column). In this case, it prints every second word in ps output lines, which means every PID.

If you have other questions, I will add the answers below.

+2
source

Here is an explanation of the code snippets that you do not understand:

1.

 # Does this mean, that the COMMAND variable can adopt different values, depending on # what is entered as parameter? "memcached" is chosen by default, port, ip address and # memory size are options, but what is -v? COMMAND="$CMD -p $PORT -l $LISTEN_IP -m $MEM_SIZE -v" 

In a person around -v:

 $ man memcached ... -v Be verbose during the event loop; print out errors and warnings. ... 

2.

 # ps -ef: Display uid, pid, parent pid, recent CPU usage, process start time, # controling tty, elapsed CPU usage, and the associated command of all other processes # that are owned by other users. # The rest of this line I don't understand, especially grep -v grep ps -ef | grep -v grep | grep $( cat $PID ) 

Print all the details of the processes ( ps -ef ), exclude the line with grep ( grep -v grep ) (since you use grep, it will be displayed in the process list) and filter by the text found in the file with the name $ PID ( /tmp/app.pid ) ( grep $( cat $PID ) ).

3.

 # I don't understand this function :-( kill_cmd() { SIGNAL=""; MSG="Killing " while true do ## create a list with all the pid numbers filtered by command (memcached) and user ($USR) LIST=`ps -ef | grep -v grep | grep $CMD | grep -w $USR | awk '{print $2}'` ## if $LIST is not empty... proceed if [ "$LIST" ] then echo; echo "$MSG $LIST" ; echo ## kill all the processes in the $LIST (xargs will get the list from the pipe and put it at the end of the kill command; something like this < kill $SIGNAL $LIST > ) echo $LIST | xargs kill $SIGNAL # Why this sleep command? ## some processes might take one or two seconds to perish sleep 2 SIGNAL="-9" ; MSG="Killing $SIGNAL" ## if the file $PID still exists, delete it if [ -f $PID ] then /bin/rm $PID fi ## if list is empty else echo; echo "All killed..." ; echo ## get out of the while loop break fi done } 

This function will kill all processes related to memcached slowly and painfully (in fact, quite the opposite). The above are explanations.

+1
source

Source: https://habr.com/ru/post/1445087/


All Articles