Shall I go for uid or ppid?

Hi Guys,
I'd like to ask your advice on the following, I've written this script to terminate a given process by name:

#!/bin/bash
echo 'Please enter the process you wish to terminate'
read process
pid=$(pidof $process)
kill -9 $pid
echo $2

to make it safer I want it to reject the killing of root owned processes.

I'm thinking of doing it using an if condition in two ways, either by the process parend ID or the process UID but I'm having some trouble getting there:

#!/bin/bash
echo 'Please enter the process you wish to terminate'
read process
pid=$(pidof $process)
ps -ef | grep '$process' | awk '{print $2}'
if [ '$2'="root"]
then
echo "The process cannot be terminated for safety reasons"
else
kill -9 $pid
echo $3

From what I understand there is no real command to get a ppid of a process so I'm trying to make it through the UID. What would you suggest?

Lora

Unless your script runs with with full privilege, processes owned by root will not be stoppable.

If your system has the /proc filesystem you have a command called either ptree or pstree (Solaris; Linux). You can use one of them to find a ppid.

Using a uid may be a problem - on many systems there are generic user names that applications installations have created & are used to run dozens of batch and background processes. Example: oracle. Kill one of them and you have serious problems.

I guess I do not understand your approach at all.

  • Another user id but root has usually no permission to kill processes of root.
  • Your script assmues that people would have to know which processes exist and how to get the pid of the one to kill. If they are capable to issue a ps they are usually also able to issue a kill - so I don't know if a script for such a task is useful (no offence).
  • Anyway you could do a "grep -v ^root" to spare out root processes.
  • ppid is always the pid listed in the second row following a ps -ef output. The header should show. Also /proc has much info about your processes.

---------- Post updated at 01:13 PM ---------- Previous update was at 01:13 PM ----------

Sorry, was interrupted while writing an answer - see Jim's answer :slight_smile:

Thank you Jim and Zaxxon,

Maybe I'm just overcomplicating things, the main idea was for the script not to take any root processes as argument

I think sparing root processes with grep -v ^root seems the quickest way to target this, but I am not sure of how to implement it?

Lora

It's very common to use grep to grovel through ps output, but keep in mind that most approaches that do this do so in a very sloppy manner, which is prone to false positives.

Typically, it's better to use AWK, so that at the very least the process name sought can be easily constrained to the the beginning of the command field (this can be done with grep, but not as easily). Otherwise, a matching username, option on the command line, or environment variable or value (which may be present depending on ps options) could match unwanted processes.

Most grep approaches also use two greps, the second to exclude the first grep from the list, which means such an approach isn't suitable if the process name contains "grep" (such as grep, egrep, fgrep, etc).

If your system has pgrep/pkill, they are almost always the best option.

Unless your script is running with root privileges, regardless of which command you use, you cannot kill any root-owned processes. Not only that, you cannot kill any processes by other unprivileged users. You can only kill processes that you own.

If the script runs SUID root, make sure you understand the security implications of such a decision.

You can use ps to get a processes' parent id. For example, the following posix-compliant ps invocation returns the current shell execution environment's parent process id:

ps -o ppid= -p $$

Regards,
Alister