ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
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-) 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.
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.
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.
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
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.
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
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.
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.
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.