views:

100

answers:

6

I have a for loop to get the list of PID's and kill each PID. I want to display the entire line of PS output and write it to the /tmp/outfile . But from each line of PS output each field(PID,PPID,...) is written along with a new line in the /tmp/outfile. So if PS output has three lines as output i want to log these three lines into /tmp/outfile but it's breaking each field in the line and adding a new line. how can i do it.

for list in `ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep`
do
     echo "$list" >> $CUSTOM_TMP/test5566
     PID=`echo $list | awk '{print $2}'`
     kill -TERM "$list"
done
+1  A: 

Isn't it easier to use the killall command for what you are trying to do?

Unknown
process name is passed as argument to the script. There might be 2 or 3 processes with same name so i am trying to kill it. If i do the above way instead of killall what i can do
Arav
Probably, but the OP wants to do it with a shell script :)
Tim Post
Thanks a lot for the info
Arav
+3  A: 

Your for loop does not iterate the lines but each individual field. Also your kill command was slightly wrong. Just change your code to something like:

ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep | while read list
do
     echo "$list" >> $CUSTOM_TMP/test5566
     PID=`echo $list | awk '{print $2}'`
     kill -TERM "$PID"
done
macgarden
+1 for `while read`
Dennis Williamson
Thanks a lot for the info. If the PS output has no record found i want to write it to the log file. I tried the below way and it's not working. if [ "${list}" = "" ]; then echo "No Process Name found - Grep no records found" fi
Arav
Also if the kill command fails i want to redirect the error output to a variable and write it to a log file using a custom API. The problem here if the PS error output has multiple lines when i move it to the variable it replaces the new line with space. Not surehow can i correct this. with APILOG function i can pass only variable as arguments. kill -TERM "$PID" 2> $CUSTOM_TMP/error_kill if [ $? -ne 0 ]; then ERROR=$(<$CUSTOM_TMP/error_kill) WriteAPILog ERROR "Error Message: $ERROR" rm $CUSTOM_TMP/error_kill fi
Arav
Thanks a lot for the info
Arav
A: 

You want to run ps before looping:

ps -ef | grep $"{process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep > $CUSTOM_TMP/test5566 2>/dev/null

for PID in `cat $CUSTOM_TMP/test5566 | awk '{print $2}'`; do
      kill -TERM $PID
done
rm -f $CUSTOM_TMP/test5566

I would also insert some sanity, possibly using wc to make sure the file actually got some data from ps.

Tim Post
Thanks a lot for the info
Arav
+1  A: 

No need for a loop at all. And this uses tee to write your temp file.

list=$(ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep | tee $CUSTOM_TMP/test5566 | awk '{printf "%s ", $2')
kill -TERM $list
Dennis Williamson
Thanks a lot for the info. If the PS output has no record found i want to write it to the log file. I tried the below way and it's not working. if [ "${list}" = "" ]; then echo "No Process Name found - Grep no records found" fi
Arav
Also if the kill command fails i want to redirect the error output to a variable and write it to a log file using a custom API. The problem here if the PS error output has multiple lines when i move it to the variable it replaces the new line with space. Not sure how can i correct this. with APILOG function i can pass only variable as arguments. kill -TERM "$PID" 2> $CUSTOM_TMP/error_kill if [ $? -ne 0 ]; then ERROR=$(<$CUSTOM_TMP/error_kill) WriteAPILog ERROR "Error Message: $ERROR" rm $CUSTOM_TMP/error_kill fi
Arav
@arav: It would be easier to read if you posted your followup code as an edit to your original question. As for your `if [ "${list}" = "" ]` snippet, I see no problem with it, assuming the `fi` is intended to be on a separate line (if not you need to put a semicolon before it). By the way "it's not working" is not at all helpful. We can be much better at helping you if you include error messages and specific ways in which the results differ from what you expect. I don't know how your custom API works, but here is how Bash works: `variable=$(<file); echo $variable; echo "$variable"`. The ...
Dennis Williamson
...first `echo` outputs all the contents of the file on one line separated by one space per "word" (multiple spaces are collapsed into one). The second `echo` outputs the contents of the file in a format similar to the original file. The quotation marks preserve the newlines and any extra whitespace.
Dennis Williamson
Thanks a lot for the info
Arav
A: 

Just move the awk part to the top line, otherwise your code is fine.

for list in `ps -ef | grep "${process_name}" | grep -v "${SCRIPTNAME}" | grep -v grep | awk '{print $2}`

do
     echo "$list" >> $CUSTOM_TMP/test5566
     PID=`echo $list`
     kill -TERM "$list"
done
Daniel t.
Thanks a lot for the info
Arav
A: 

For a one liner - if your system has pgrep --

pgrep -d ' ' ${process_name} > kill.log && kill -TERM $(< kill.log)
jim mcnamara