0

We have a script that fetches all the active processes and kills it . But for some reason i am getting the below error :

:: INFO :: /AA/AAA/AAA/AAA/AAA/AAA/AAA/AAA\ Servers.sh :: 2016-06-26:04:00:04 : FORCE KILLING REMAINING SERVER PROCESSES

:: INFO :: /AA/AAA/AAA/AAA/AAA/AAA/AAA/AAA\ Servers.sh :: 2016-06-26:04:00:04 :force_stop_managed_servers calledkill: usage\ : kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspe\ c]

My Script has the below function to force kill the processes.

function force_stop_managed_servers () {

        printf "\n\n:: INFO :: $0 :: `date +%Y-%m-%d:%H:%M:%S` :force_stop_managed_servers called"
        cd $SCRIPT_DIR
        kill -9 $(ps -ef | grep SONARPOTY | grep $USER | grep -v "grep" | grep -v "StopManagedServers" | grep -v "controller"| awk '{ print $2 }')
        printf "\n\n:: INFO :: $0 :: `date +%Y-%m-%d:%H:%M:%S` :force_stop_managed_servers done"
}

Please let me know why am i getting this error.

  • Try it with `set -x` and you'll probably see that `kill` gets called wrong. (Also, http://www.shellcheck.net will show you have some other potential errors.) – Biffen Jun 27 '16 at 07:58
  • Ensure whether `$USER` is not empty and also the there is only one pid returned as result of the big command. – Fazlin Jun 27 '16 at 12:24
  • @Fazlin : The long command will NOT return a single process ID . It will return multiple processes. Can you please suggest what is the drawback if it returns multiple processes and also a possible solution to overcome that ? – MAHESH KUMAR Jun 27 '16 at 13:32
  • I do not want to use a for loop, because the for loop will kill the processes one by one and it is possible that once i fetch the list and kill them one by one the process might have got completed and then the kill command will error out telling _No Such process_. – MAHESH KUMAR Jun 27 '16 at 13:35
  • As far as i know, `kill` command does not work with multiple pid.s as argument. You might have to use loop. – Fazlin Jun 28 '16 at 07:52
  • 1
    @Fazlin : It does work with multiple PID's. As i mentioned above, _for_ loop is having the above drawback .. Moreover, The issue is intermittent. It doesn't comes always. one sometimes i see the issue and otherwise it works fine . So the uestion is which is that edge case where i am getting that issue. – MAHESH KUMAR Jun 28 '16 at 09:43
  • Why not use `pkill -9 -u $USER 'pattern1|pattern2|pattern3'`? – alvits Jul 10 '17 at 21:25
  • @Fazlin - Here's the manpage of [kill(1)](https://linux.die.net/man/1/kill). – alvits Jul 10 '17 at 21:29

2 Answers2

0

This error is possible if 'kill -9' command called without argument. You can execute the long line command and assign the output to a variable. Later check that variable for not empty and pass that variable as argument to kill command.

JP Bose
  • 22
  • 5
0

The procps package has better capability in handling process selection and sending signals to selected processes than util-linux-ng package combined with grep.

It is very common to see scripts that use grep to select a process id from the list of processes.

ps -ef | grep pattern | grep -v grep | awk '{print $2}'

However, this can be shortened to:

pgrep pattern

Both cases will print the PID of the process whose name is pattern. There is one caveat though, the second version only matches the pattern against process names. If you need to match against command arguments you need something like:

pgrep -f pattern

Limiting the search for processes owned by user. Some attempts to grep username. Both pgrep and ps accepts -u username to list only the processes owned by user username.

Instead of writing:

ps -ef | grep username | grep -v grep | awk '{print $2}'

Try:

pgrep -u username

If you need to kill these selected PIDs, you won't need to run kill against the results. All you need is to use pkill instead of pgrep.

pkill -u username pattern

If you are truly limited to using ps and kill for whatever reason you may have, ps allows a formatted output. This way you can grep for pattern without inadvertently getting the PID of the grep itself.

kill -9 $(ps -u username -opid=.comm= | grep pattern | awk '{print $1}')

The only drawback with using kill $() is that $() may return empty and you'll get the error message you get. The solution is to toss the error message to /dev/null. pkill will not complain even when there is nothing to kill.

Finally, if you need to match against a command argument instead of the command itself, use -opid=,args= to output the arguments instead outputting the command.

alvits
  • 6,550
  • 1
  • 28
  • 28