LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 06-03-2005, 11:33 AM   #1
naimslim89
Member
 
Registered: Mar 2005
Location: London, United Kingdom
Distribution: Fedora Core 5
Posts: 83

Rep: Reputation: 15
Bash: Check if a program is running


Hello All,

I'm using Xorg 6.8.2 and the new composite extension. The visual effects are great, however it is still buggy.

One of the things that happen is that when I click (in GNOME) on Log Out, X crashes.

I've had to get around the problem by killing Xcompmgr (the composite manager) just before I log off. This gets tedious, having to do it every time I log out.

So I decided to make a custom application launcher, which runs a shell script when clicked on.

What I want the shell script to do is check if the program is already running or not, before it does anything. Basically, it'll act as a switch -- if xcompmgr is running, it'll kill it, and if it isn't running, it'll start it. What I need to know is how to get the script to check whether it's running or not.

The test command in bash scripting can only test certain things, most of them file based.

Here's my script as it stands:

Code:
#!bin/bash

if [ <my test goes here -- needs to return a true value if the process is running> ]
then killall xcompmgr
else exec xcompmgr -c -f
fi
Thanks for your time.
 
Old 06-03-2005, 12:43 PM   #2
acid_kewpie
Moderator
 
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,414

Rep: Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966Reputation: 1966
many ways, e.g.
Code:
if [ "$(pidof process_name)" ] 
then
  # process was found
else
  # process not found
fi

Last edited by acid_kewpie; 06-03-2005 at 12:45 PM.
 
Old 06-04-2005, 03:30 AM   #3
naimslim89
Member
 
Registered: Mar 2005
Location: London, United Kingdom
Distribution: Fedora Core 5
Posts: 83

Original Poster
Rep: Reputation: 15
Thank you very much, that was exactly what I was looking for!
 
Old 09-20-2009, 09:10 AM   #4
waldeck
LQ Newbie
 
Registered: Sep 2009
Posts: 1

Rep: Reputation: 1
How to check if another instance of same script is running

Just to add my 5 cents to this discussion, if you want to check whether another instance of the same script is running you might want to try this:

Code:
if pidof -x $(basename $0) > /dev/null; then
  for p in $(pidof -x $(basename $0)); do
    if [ $p -ne $$ ]; then
      echo "Script $0 is already running: exiting"
      exit
    fi
  done
fi
 
1 members found this post helpful.
Old 02-13-2010, 08:22 PM   #5
Gimlic
LQ Newbie
 
Registered: Feb 2010
Posts: 1

Rep: Reputation: 0
I'm not sure what the difference is between pidof and pgrep, but I use the latter.

Code:
if [ -z "$(pgrep foo)" ]
  then
     # foo is not running
  else
     # foo is running
fi

Last edited by Gimlic; 02-13-2010 at 08:25 PM.
 
Old 12-24-2011, 04:48 PM   #6
penguen
LQ Newbie
 
Registered: Dec 2011
Posts: 1

Rep: Reputation: Disabled
The difference I see between pidof and pgrep is:

1-) pgrep greps the given process name where as pidof exactly matches the process name. ie pidof may not find processes name /bin/bash but pgrep will find all processes containing bash key.
2-) pidof separator is blank space while pgrep separator is newline.
 
Old 12-27-2011, 05:36 AM   #7
jv2112
Member
 
Registered: Jan 2009
Location: New England
Distribution: Arch Linux
Posts: 718

Rep: Reputation: 102Reputation: 102
Lightbulb

If you just want to kill the system....



Code:
#! /bin/bash/

shutdown -h now .... Goodbye $USER

exit 0
 
Old 05-04-2012, 04:38 AM   #8
Stainy
LQ Newbie
 
Registered: May 2012
Posts: 3

Rep: Reputation: Disabled
also

Hi guys...

I would like to use a script like the one in this thread for checking on whether a process is running or not.
My situation is a tiny bit more complex.

I have a file generated that holds all the pids that I want to monitor.

How can I check on all these process`s to check whether one goes down or not? using the script in this thread??

anyone have any ideas?

Darren
 
Old 05-04-2012, 12:49 PM   #9
jv2112
Member
 
Registered: Jan 2009
Location: New England
Distribution: Arch Linux
Posts: 718

Rep: Reputation: 102Reputation: 102
Not tested...

Code:
#! /bin/bash
check_it () 
{
wc -l file w/ PID > List
sleep 10

wc -l file w/ PID >Check

if [[ $(wc -l Check) -lt $(wc -l List) ]]
then
echo "Process Ended"
else
echo "No Issue"
fi

}


while [1] then check_it

exit
 
Old 05-08-2012, 07:14 AM   #10
Stainy
LQ Newbie
 
Registered: May 2012
Posts: 3

Rep: Reputation: Disabled
Quote:
Originally Posted by jv2112 View Post
Not tested...

Code:
#! /bin/bash
check_it () 
{
wc -l file w/ PID > List
sleep 10

wc -l file w/ PID >Check

if [[ $(wc -l Check) -lt $(wc -l List) ]]
then
echo "Process Ended"
else
echo "No Issue"
fi

}


while [1] then check_it

exit
Hmmm it does bum out on the 'while' saying not matched...

I take it there`s no differences with korn shell?

also this is my understanding wc -l <pathtofile> > List?


Darren
 
Old 05-08-2012, 08:28 AM   #11
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
If you have a list of process IDs in file pidlist, first read it into a variable. For illustration, I'll use sed to edit out any non-PIDs, and read them into a space-separated string.
Code:
PIDS="$(sed -ne 's|^[\t\v\f ]*\([0-9]\+\)[\t\v\f ]*$|\1|p' pidlist | tr -s '[[:space:][:cntrl:]]' ' ')"
You might wish to use [ -n "$PIDS" ] at this point to verify there is at least one PID in PIDS.

Next, use ps to list the PIDs of still existing processes. Try to do it using a single command, because the ps command overhead is quite large. Only calling it once will be significantly faster than calling it for each PID separately.
Code:
ALIVE=" $(ps -o pid= -p "${PIDS[*]}" | tr -s '[[:space:][:cntrl:]]' ' ') "
Note that this one will have a space before and after every PID, including at the start and end of the string. This way, in Bash, you can use [ "$ALIVE" != "${ALIVE/ $PID /}" ] to test if PID is listed in ALIVE.

The only thing left to do is to check which PIDs from PIDS are listed in ALIVE.
Code:
for PID in $PIDS ; do
    if [ "$ALIVE" != "${ALIVE/ $PID /}" ]; then
        echo "Process $PID is still alive."
    else
        echo "Process $PID has died."
    fi
done
If you just want arrays of the PIDs that are still running or have died, you can rewrite the loop as
Code:
RUNNING=()
DIED=()
for PID in $PIDS ; do
    if [ "$ALIVE" != "${ALIVE/ $PID /}" ]; then
        RUNNING[${#RUNNING[@]}]=$PID
    else
        DIED[${#DIED[@]}]=$PID
    fi
done
# There are ${#RUNNING[@]} processes still running: ${RUNNING[@]}
# ${#DIED[@]} of the processes are gone: ${DIED[@]}
There is however a serious flaw in the overall logic, that should be fixed:
Because PIDs are reused eventually, the new PID could be a totally unrelated process!

To counter that, if all the processes run the same command, you could use
Code:
ALIVE=" $(ps -o pid= -C command | tr -s '[[:space:][:cntrl:]]' ' ') "
instead. This one lists all the PIDs for processes whose executable name is command. Or, if there are a few different names, use -C "cmd1 cmd2 .. cmdN" instead.
This way only existing processes running that command or those commands are considered.

There are other approaches, too. A typical one is to check that the still alive processes are in the right session or process group. I'd personally pick the approach depending on exactly what the processes are running, and how they are related. For typical servers, checking the executable name or process group is common, and those you can do by adjusting the parameters to the ALIVE ps command; instead of limiting to the set of PIDs in PIDS, look for all acceptable processes, and let the loop handle the limiting to the original set. See the man 1 ps manpage for details.

Last edited by Nominal Animal; 05-08-2012 at 08:31 AM.
 
Old 05-08-2012, 10:48 AM   #12
Stainy
LQ Newbie
 
Registered: May 2012
Posts: 3

Rep: Reputation: Disabled
Hi...

thanks so much for replying...

I`m fairly new to scripting...so I`m still trying to digest half of this

but I`m getting an error

ps: 0509-048 Flag -p was used with invalid list.
I`m guessing in korn shell it doesn`t like the p flag with the commands I`ve passed to it..

also this list of pids is static all through the day and it changes the following day.. so I can schedule this script to run during trading hours, stop and then run again the following day.. shouldn`t be a problem I think..

Darren



Quote:
Originally Posted by Nominal Animal View Post
If you have a list of process IDs in file pidlist, first read it into a variable. For illustration, I'll use sed to edit out any non-PIDs, and read them into a space-separated string.
Code:
PIDS="$(sed -ne 's|^[\t\v\f ]*\([0-9]\+\)[\t\v\f ]*$|\1|p' pidlist | tr -s '[[:space:][:cntrl:]]' ' ')"
You might wish to use [ -n "$PIDS" ] at this point to verify there is at least one PID in PIDS.

Next, use ps to list the PIDs of still existing processes. Try to do it using a single command, because the ps command overhead is quite large. Only calling it once will be significantly faster than calling it for each PID separately.
Code:
ALIVE=" $(ps -o pid= -p "${PIDS[*]}" | tr -s '[[:space:][:cntrl:]]' ' ') "
Note that this one will have a space before and after every PID, including at the start and end of the string. This way, in Bash, you can use [ "$ALIVE" != "${ALIVE/ $PID /}" ] to test if PID is listed in ALIVE.

The only thing left to do is to check which PIDs from PIDS are listed in ALIVE.
Code:
for PID in $PIDS ; do
    if [ "$ALIVE" != "${ALIVE/ $PID /}" ]; then
        echo "Process $PID is still alive."
    else
        echo "Process $PID has died."
    fi
done
If you just want arrays of the PIDs that are still running or have died, you can rewrite the loop as
Code:
RUNNING=()
DIED=()
for PID in $PIDS ; do
    if [ "$ALIVE" != "${ALIVE/ $PID /}" ]; then
        RUNNING[${#RUNNING[@]}]=$PID
    else
        DIED[${#DIED[@]}]=$PID
    fi
done
# There are ${#RUNNING[@]} processes still running: ${RUNNING[@]}
# ${#DIED[@]} of the processes are gone: ${DIED[@]}
There is however a serious flaw in the overall logic, that should be fixed:
Because PIDs are reused eventually, the new PID could be a totally unrelated process!

To counter that, if all the processes run the same command, you could use
Code:
ALIVE=" $(ps -o pid= -C command | tr -s '[[:space:][:cntrl:]]' ' ') "
instead. This one lists all the PIDs for processes whose executable name is command. Or, if there are a few different names, use -C "cmd1 cmd2 .. cmdN" instead.
This way only existing processes running that command or those commands are considered.

There are other approaches, too. A typical one is to check that the still alive processes are in the right session or process group. I'd personally pick the approach depending on exactly what the processes are running, and how they are related. For typical servers, checking the executable name or process group is common, and those you can do by adjusting the parameters to the ALIVE ps command; instead of limiting to the set of PIDs in PIDS, look for all acceptable processes, and let the loop handle the limiting to the original set. See the man 1 ps manpage for details.
 
Old 05-08-2012, 10:24 PM   #13
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942Reputation: 942
Quote:
Originally Posted by Stainy View Post
ps: 0509-048 Flag -p was used with invalid list.
Are you running on AIX?

Try comma-separated lists:
Code:
PIDS="`tr -cd '0-9\r\n' < pidfile | tr -s '[\n\r ]' ','`"
PIDS="${PIDS//,,/,}"
PIDS="${PIDS##,}"
PIDS="${PIDS%%,}"


# If you know the executables, use
ALIVE=",`ps -o pid= -C 'cmd1,cmd2,...,cmdN' | tr -s '[\t\n\v\f\r ]' ','`,"
# otherwise, use
ALIVE=",`ps -o pid= -p $PIDS | tr -s '[\t\n\v\f\r ]' ','`,"


for PID in ${PIDS//,/ } ; do
    if [ "$ALIVE" != "${ALIVE/,$PID,/}" ]; then
        echo "$PID still running"
    else
        echo "$PID has exited"
    fi
done
Note that if you set IFS="," then the for loop is written for PID in $PIDS ; do .
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Obtain ip address and check for running process via Bash Script? xconspirisist Programming 10 09-12-2008 01:18 PM
KDE - please check that the "DCOPserver" program is running Thanotos Linux - Newbie 2 11-27-2006 06:11 PM
Check if program is running Conjurer Programming 8 11-17-2005 01:37 PM
Bash Script - How do I make sure my program is still running? nro Linux - Newbie 4 08-28-2005 01:57 PM
program to check to make sure a process is running? IceNineJon Linux - Software 7 08-06-2003 02:07 PM


All times are GMT -5. The time now is 11:13 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration