Check for process and kill if running

18,020

Solution 1

Your syntax has many problems:

  • remove spaces around "=" when setting a variable

    wrong:

    APP_ID = value
    

    right:

    APP_ID=value
    
  • to run a program and put its output into a variable, you need $(...) (preferred in bash, not available in sh) or backticks `command` (supported in bash and sh). (and remember that when assigning a variable, quotes are not needed, but in other cases they are important: command "$(command)")

    wrong:

    APP_ID=command
    

    right:

    APP_ID=$(command)
    
  • add spaces around everything when using "[", and you need a semicolon or newline after the "]". This is because "[" is a bash builtin command, and the non-builtin one is also known as "test" (see man test), which just like other commands, takes its arguments separated by space:

    wrong:

    if[x!= y] then echo hello world fi
    

    right:

    if [ x != y ]; then echo hello world; fi
    
  • use double quotes, not single quotes when you want to expand a variable

    wrong:

    if [ '' != '${APP_ID}' ]; then
    

    right:

    if [ '' != "${APP_ID}" ]; then
    
  • Also for the above example, you can use -n (non-empty) instead of comparing to empty string

    if [ -n "${APP_ID}" ]; then
    
  • And for the ps example, you don't need grep and awk:

    APP_ID=$(ps -C whoami --no-header --format 'pid')
    

And so here is the fixed up script:

APP_ID=$(ps -C whoami --no-header --format 'pid')

if [ -n "${APP_ID}" ]; then
    echo "Stopping instance $APP_ID"
fi

Solution 2

This is easiest done with pgrep and pkill:

if pgrep process_name 2>/dev/null; then
  echo "Terminating process_name"
  pkill process_name
fi

As user @OrangeDog points out in the comments, there is the theoretical possibility of this shell code failing to terminate the process process_name if the process spawns inbetween the call to pgrep and pkill. In this case, pgrep would not detect the process and pkill would never execute. How much of a problem this is, I don't know. If the process spawns just after the statement, what can you do?

Just do

echo "terminating process_name (if it is running)"
pkill process_name

to be rid of the pesky race condition in any case.

Solution 3

I am not sure why but the above script was not giving any syntax issues but was not giving the process id also though the process was running.

I finally changed it as below and it works -

APP_ID=$(ps -ef | grep <app_name> | grep java | awk '{print $2}')

echo "Instance $APP_ID"
if [ -n "${APP_ID}" ]; then
    echo "Stopping instance $APP_ID"
fi

Thanks once again for the explanation and pointers.

@Peter I will check again the script you posted on why it is not working for me.

Share:
18,020

Related videos on Youtube

user179309
Author by

user179309

Updated on September 18, 2022

Comments

  • user179309
    user179309 over 1 year

    I am trying to find if a process is running or not, and if it is runing then I want to call a script or print something. I tried with the below few ways, but it gives me syntax error or command not found error.

    APP_ID = ps -eaf | grep -i `whoami` | grep -i <process_name> | grep -i java | awk '{print$2}'
    
    if[''!= '${APP_ID}'] then
        echo "Stopping instance $APP_ID"
    

    I get the result as below:

    test.sh: line 15: APP_ID: command not found
    test.sh: line 17: if[!= ${APP_ID}]: command not found
    Stopping instance 
    

    What is wrong in the above script? And if it has some errors, then why does it print the echo in the if condition?

    Also the below script fails saying test.sh: line 3: [ps: command not found

    if [ps -eaf | grep -i `whoami` | grep -i <process_name> | grep -i java]; then
        echo 'stop'
    fi
    
  • ctrl-alt-delor
    ctrl-alt-delor almost 8 years
    [ is a built in of bash. But behaves as if it is a separate command. On some shells it is. You can find [ in /usr/bin/[, and it has a man page.
  • user179309
    user179309 almost 8 years
    Thanks for the reply. Do we need to provide the pid in the above script ? I just have the process name which I want to stop. I am very new to scripting and trying to learn hence please bear with me for the stupid questions.
  • vipin
    vipin almost 8 years
    @user179309 in the above script, it looks by name, just like you did with whoami, and the APP_ID will be a single or multi-line string including all the process ids (depending on how many processes are found).
  • vipin
    vipin almost 8 years
    @richard thanks, I guess you're right that I implied it's the same when it's not, so I fixed that.
  • OrangeDog
    OrangeDog almost 8 years
    Why bother checking beforehand?
  • Kusalananda
    Kusalananda almost 8 years
    @OrangeDog Because in script in the question, the OP clearly tries to do the same.
  • OrangeDog
    OrangeDog almost 8 years
    This has a race condition. The process you kill may not be the same one that you grepped for.
  • Kusalananda
    Kusalananda almost 8 years
    @OrangeDog There is technically a race condition in there in terms of what PIDs gets signalled, true. But the signal with be delivered to the instances of process_name running while pkill is executing none the less. It would have been worse if I had taken the PIDs from pgrep and fed them to kill, which might have left some recently spawned instance of process_name running. This will not be the case here.
  • Kusalananda
    Kusalananda almost 8 years
    @OrangeDog The "worst" thing that could happen is that process_name terminates before we get to pkill.
  • OrangeDog
    OrangeDog almost 8 years
    No the worst thing that happens is you kill the replacement process for the one you were supposed to be killing.
  • Kusalananda
    Kusalananda almost 8 years
    @OrangeDog If I wanted to kill a specific process, I would not use pkill, I would keep track of the PID of that process and use kill $somepid. In this case, I find it hard to come up with even an academic situation where this race condition would cause undesired results. Oh, there is one! If process_name spawns inbetween the calls, without existing before. Sigh, I'll add a note..
  • Kusalananda
    Kusalananda almost 8 years
    @OrangeDog It's still just academic. If you run pkill process_name and the process spawns just afterwards, what have you gained?
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' almost 8 years
    Don't do this ps … | grep … stuff, it's unreliable: sooner or later you'll end up killing an unrealted process with a resembling name. Use pgrep instead.