I am trying to write a bash script to find duplicate instances of python scripts running on a Pi. The following script is working and identifies the Python (not Python3 intentionally) of duplicates instances of the same script. I get the PID as expected but I am not able to get the full path and name of the script.
I have created a couple instance of a script:
bms 9189 0.0 0.1 10592 7248 ? S 09:11 0:00 python -u /home/bms/Dev/APItest/APItest.py
bms 9192 0.0 0.1 10592 7188 ? S 09:12 0:00 python -u /home/bms/Dev/APItest/APItest.py
This is the output I get from the bash script:
Found 2 instances of -u:
PID: 9189, Script path: -u
PID: 9192, Script path: -u
Finished checking for duplicate Python scripts.
I was expecting to get an output like:
PID: 9189, Script path: home/bms/Dev/APItest/APItest.py
PID: 9192, Script path: home/bms/Dev/APItest/APItest.py
And this is the script I am using:
#!/bin/bash
# Get a list of all running Python processes
PYTHON_PROCESSES=$(ps aux | grep '[p]ython' | grep -v 'python3' | awk '{print $2}')
# Loop through the Python processes and count how many times each script is running
declare -A SCRIPT_COUNTS
declare -A SCRIPT_PIDS
for PID in $PYTHON_PROCESSES; do
CMD=$(ps -p $PID -o comm=)
if [ "$CMD" == "python" ]; then
SCRIPT_ARGS=$(ps -p $PID -o args=)
SCRIPT_PATH=$(echo "$SCRIPT_ARGS" | awk '{print $2}')
SCRIPT_NAME=${SCRIPT_PATH##*/}
if [ -z "${SCRIPT_COUNTS[$SCRIPT_NAME]}" ]; then
SCRIPT_COUNTS[$SCRIPT_NAME]=0
fi
((SCRIPT_COUNTS[$SCRIPT_NAME]++))
if [ -z "${SCRIPT_PIDS[$SCRIPT_NAME]}" ]; then
SCRIPT_PIDS[$SCRIPT_NAME]=""
fi
SCRIPT_PIDS[$SCRIPT_NAME]="${SCRIPT_PIDS[$SCRIPT_NAME]}$PID:$SCRIPT_PATH "
fi
done
# Loop through the script counts and print the names of any scripts that have duplicates
for SCRIPT_NAME in "${!SCRIPT_COUNTS[#]}"; do
COUNT=${SCRIPT_COUNTS[$SCRIPT_NAME]}
if [ $COUNT -gt 1 ]; then
echo "Found $COUNT instances of $SCRIPT_NAME:"
for INSTANCE in ${SCRIPT_PIDS[$SCRIPT_NAME]}; do
PID=${INSTANCE%%:*}
SCRIPT_PATH=${INSTANCE#*:}
echo "PID: $PID, Script path: $SCRIPT_PATH"
done
fi
done
echo "Finished checking for duplicate Python scripts."
Apologise if there is any misalignment in the code. Had to adjust it manually to fit it in the canvas.
My question is: what should I change to get the desired output ( PID plus full path and name of the duplicates).
Why not this simple awk ?
$ <INPUT> | awk '{print "PID: " $2 ", Script path: " $NF}' file
PID: 9189, Script path: /home/bms/Dev/APItest/APItest.py
PID: 9192, Script path: /home/bms/Dev/APItest/APItest.py
Related
Objective: Check for zombie processes, but if any are found to be owned by the account nagios, ignore them. If a zombie process is found to be owned by an account other than the nagios account, then issue an alert.
Currently have the following nagios check in the nrds.cfg to find zombie processes.
command[Check_ZombieProcs]=/opt/tools/nagitem/libexec/check_procs -w 1 -c 2 -s Z
Which will generate output like this when it finds something:
PROCS CRITICAL: 3 processes with STATE = Z | procs=3;1;2;0;
To find out who owns the above following 3 defunct zombie processes, I can manually run the command:
ps -elf | grep Z | grep "defunct" which results in the output shown below.
0 Z nagios 9487 9948 0 80 0 - 0 do_exi Nov07 ? 00:00:00 [sh] <defunct>
0 Z nagios 28647 9949 0 80 0 - 0 do_exi Nov03 ? 00:00:00 [sh] <defunct>
0 Z nagios 67429 9947 0 80 0 - 0 do_exi Nov03 ? 00:00:00 [sh] <defunct>
My problem is that the defunct processes shown above end up clearing on their own and I want to exclude from the output any defunct zombie processes owned by the account nagios.
Since the check_procs nagios plugin does not have an argument to handle the exclusion of a user, I am creating the following script.
With the script below, what I want to accomplish is:
If status is equal to null or is equal to nagios, then state should be ok (green).
If status is equal to anything other than null or nagios, then state should be critcal (red).
#!/bin/ksh
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3
SCRIPTPATH=`echo $0 | /bin/sed -e 's,[\\/][^\\/][^\\/]*$,,'`
if [[ -f ${SCRIPTPATH}/utils.sh ]]; then
. ${SCRIPTPATH}/utils.sh # use nagios utils to set real STATE_* return values
fi
printvariables() {
echo "Variables:"
#Add all your variables at the end of the "for" line to display them in verbose
for i in EXITSTATUS EXITMESSAGE
do
echo -n "$i : "
eval echo \$${i}
done
echo
}
#Set to unknown in case of unexpected exit
EXITSTATUS=$STATE_UNKNOWN
EXITMESSAGE="UNKNOWN: Unexpected exit. You should check that everything is alright"
ZOMB=$(ps -elf | grep Z | grep "defunct" | awk {'print $3'} | sort -u)
if [ "$ZOMB" == "nagios" ];then
EXITSTATUS=$STATE_OK
EXITMESSAGE="OK - No Defunct processes found"
elif [ "$ZOMB" == "" ];then
EXITSTATUS=$STATE_OK
EXITMESSAGE="OK - No Defunct processes found"
else
EXITSTATUS=$STATE_CRITICAL
EXITMESSAGE="CRITICAL - Defunct processes found owned by $ZOMB"
fi
#Script end, display verbose information
if [[ $VERBOSE -eq 1 ]] ; then
printvariables
fi
echo ${EXITMESSAGE}
exit $EXITSTATUS
The command:
ps -elf | grep Z | grep "defunct" | awk {'print $3'}
has the potential to give output similar to the following which no doubt will cause an issue. I cannot replicate or thoroughly test as I only occasionally see a defunct process.
nagios
root
someuser
Note that in my script above I am using (see the sort -u):
ps -elf | grep Z | grep "defunct" | awk {'print $3'} | sort -u
to eliminate getting the same account (like nagios) listed multiple times in the output. My script above does work, but I am concerned that it cannot handle if there is more than one account that has defunct processes.
Appreciate any help.
This is more of a bash question than a nagios question, but I'll bite.
The first issue I see is that you're simply pushing all output from ps into $ZOMB when what you probably want to do is to iterate over each line (process).
You could do something like this:
For each line in the ps output, check if it's a zombie process. If not, discard it.
If yes, check whether the user is nagios, if so discard it.
If not, we have a problem, so exit 1 and say what the user and process is.
Example:
#!/bin/bash
echo "$(ps -elf)" | while IFS= read -r line ;
do
user=$(echo "$line" | awk {'print $3'})
stat=$(echo "$line" | awk {'print $2'})
proc=$(echo "$line" | awk {'print $15'})
if [ "$stat" != "R" ]; then
# it's not running, we don't care
continue
elif [ "$user" == "root" ]; then
# it's root, we don't care
continue
else
# we do care! print info and exit 1 immediately
echo "Found process: $user '$proc'"
exit 1
fi
done
In your case, "R" would be "Z" and "root" would be "nagios".
I have this init.d script where i am checking the status of an application, The expected output should be
"Application is running with PID: XXXX"
Anyways, i'll show you the code that i have used:
ps -ef|grep -v grep |grep Jazz |grep -v "Jazz status"|awk '{ if ( $2 != "") print "Jazz Running with PID:",$2"; else print "Jazz not running";}'
When i run this on the terminal i get the following output:
Jazz Running with PID: 6261
Jazz Running with PID: 30077
When i remove the print statement and output $2 i get the following output:
#ps -ef|grep -v grep |grep Jazz |grep -v "Jazz status"|awk '{ if ( $2 != "") print $2}'
300077
I expect the output to be
Jazz Running with PID: 300773
I am stumped as to why i am getting two PID's in the first case?
P.S the first PID keeps changing, similar to showing me the PID of the command itself.
Edit:
Output of: ps -ef|grep Jazz
netcool 12744 1 5 13:03 ? 00:06:06 /opt/IBM/tivoli/webSphere/AppServer/java/bin/java -Declipse.security -Dwas.status.socket=38692 -Dosgi.install.area=/opt/IBM/tivoli/webSphere/AppServer -Dosgi.configuration.area=/opt/IBM/tivoli/jazzSM/profile/servers/server1/configuration -Djava.awt.headless=true -Dosgi.framework.extensions=com.ibm.cds,com.ibm.ws.eclipse.adaptors -Xshareclasses:name=webspherev85_1.6_64_%g,nonFatal -Xbootclasspath/p:/opt/IBM/tivoli/webSphere/AppServer/java/jre/lib/ibmorb.jar -classpath /opt/IBM/tivoli/jazzSM/profile/properties:/opt/IBM/tivoli/webSphere/AppServer/properties:/opt/IBM/tivoli/webSphere/AppServer/lib/startup.jar:/opt/IBM/tivoli/webSphere/AppServer/lib/bootstrap.jar:/opt/IBM/tivoli/webSphere/AppServer/lib/jsf-nls.jar:/opt/IBM/tivoli/webSphere/AppServer/lib/lmproxy.jar:/opt/IBM/tivoli/webSphere/AppServer/lib/urlprotocols.jar:/opt/IBM/tivoli/webSphere/AppServer/deploytool/itp/batchboot.jar:/opt/IBM/tivoli/webSphere/AppServer/deploytool/itp/batch2.jar:/opt/IBM/tivoli/webSphere/AppServer/java/lib/tools.jar -Dibm.websphere.internalClassAccessMode=allow -Xms512m -Xmx1024m -Xcompressedrefs -Xscmaxaot4M -Xscmx60M -Dws.ext.dirs=/opt/IBM/tivoli/webSphere/AppServer/java/lib:/opt/IBM/tivoli/jazzSM/profile/classes:/opt/IBM/tivoli/webSphere/AppServer/classes:/opt/IBM/tivoli/webSphere/AppServer/lib:/opt/IBM/tivoli/webSphere/AppServer/installedChannels:/opt/IBM/tivoli/webSphere/AppServer/lib/ext:/opt/IBM/tivoli/webSphere/AppServer/web/help:/opt/IBM/tivoli/webSphere/AppServer/deploytool/itp/plugins/com.ibm.etools.ejbdeploy/runtime -Dderby.system.home=/opt/IBM/tivoli/webSphere/AppServer/derby -Dcom.ibm.itp.location=/opt/IBM/tivoli/webSphere/AppServer/bin -Djava.util.logging.configureByServer=true -Duser.install.root=/opt/IBM/tivoli/jazzSM/profile -Djava.ext.dirs=/opt/IBM/tivoli/webSphere/AppServer/tivoli/tam:/opt/IBM/tivoli/webSphere/AppServer/java/jre/lib/ext -Djavax.management.builder.initial=com.ibm.ws.management.PlatformMBeanServerBuilder -Dpython.cachedir=/opt/IBM/tivoli/jazzSM/profile/temp/cachedir -Dwas.install.root=/opt/IBM/tivoli/webSphere/AppServer -Djava.util.logging.manager=com.ibm.ws.bootstrap.WsLogManager -Dserver.root=/opt/IBM/tivoli/jazzSM/profile -Dcom.ibm.security.jgss.debug=off -Dcom.ibm.security.krb5.Krb5Debug=off -Dfas.install.location=/opt/IBM/tivoli/jazzSM/admin -Dfas.ui.install.location=/opt/IBM/tivoli/jazzSM/admin_ui -Djava.library.path=/opt/IBM/tivoli/webSphere/AppServer/lib/native/linux/x86_64/:/opt/IBM/tivoli/webSphere/AppServer/java/jre/lib/amd64/default:/opt/IBM/tivoli/webSphere/AppServer/java/jre/lib/amd64:/opt/IBM/tivoli/webSphere/AppServer/bin:/usr/lib:/opt/IBM/tivoli/jazzSM/reporting/cognos/bin64: -Djava.endorsed.dirs=/opt/IBM/tivoli/webSphere/AppServer/endorsed_apis:/opt/IBM/tivoli/webSphere/AppServer/java/jre/lib/endorsed:/opt/IBM/tivoli/webSphere/AppServer/endorsed_apis:/opt/IBM/tivoli/webSphere/AppServer/java/jre/lib/endorsed -Djava.security.auth.login.config=/opt/IBM/tivoli/jazzSM/profile/properties/wsjaas.conf -Djava.security.policy=/opt/IBM/tivoli/jazzSM/profile/properties/server.policy com.ibm.wsspi.bootstrap.WSPreLauncher -nosplash -application com.ibm.ws.bootstrap.WSLauncher com.ibm.ws.runtime.WsServer /opt/IBM/tivoli/jazzSM/profile/config JazzSMNode01Cell JazzSMNode01 server1
netcool 19735 19678 0 14:50 pts/0 00:00:00 grep Jazz
Edit
Full init.d script that i have used:
#!/bin/sh
USER="xxxxxxx"
PASSWORD="xxxxxx"
start() {
su - netcool -c "/opt/IBM/tivoli/jazzSM/profile/bin/startServer.sh server1"
RETVAL=$?
return $RETVAL
}
stop() {
su - netcool -c "/opt/IBM/tivoli/jazzSM/profile/bin/stopServer.sh server1 -username ${USER} -password ${PASSWORD}"
RETVAL=$?
return $RETVAL
}
status() {
ps -ef|grep -v grep |grep Jazz |grep -v awk |grep -v "Jazz status" |awk '{ if ( $2!= "") print "Jazz is running with PID:",$2; else print "Jazz is not running";}'
#pid=$(pgrep -f Jazz) && echo "Jazz Running with PID: $pid" || echo "Jazz is not running"
}
case $1 in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart"|"reload")
stop
start
;;
*)
echo "usage: $0 {start|stop|status|restart|reload}"
RETVAL=1
esac
exit 0
Hope this helps
UPDATE
Based upon #jlliagre suggestion, running the following command still gave me more than one PID as the output:
[root#hjkpnlinst04 ~]# pid=$(pgrep -f jazzSM) && echo "Jazz Running with PID: $pid" || echo "Jazz is not running"
Jazz Running with PID: 12744
13176
13299
For now i am running this command, which seems to give me the required output when the process is running, however fails to give me the "else" output when the process is not running:
ps -ef|grep -v grep |grep Jazz |grep -v awk |grep -v "Jazz status" |awk '{ if ( $2!= "") print "Jazz is running with PID:",$2; else print "Jazz is not running";}'
That command should work (assuming pgrep is available):
pid=$(pgrep -f JazzSMNode01Cell) && echo "Jazz Running with PID: $pid" || echo "Jazz is not running"
Most likely you are finding awk. You are excluding grep, but not awk.
Better way to do this is using the pgrep command, e.g.:
echo "java is running with pids ", `pgrep java`
will list all pids Java processes are running with. It looks at the process image name only, not on the command line. I am not sure how portable pgrep is but it is there on Linux, FreeBSD and OS X, so good enough for me.
But looking at your updated answer I see that you are looking for the command line keyword, so like #jlliagre suggests, you should use -f switch. The advantage of pgrep is that it is smart enough to exclude itself, unlike the chain of awks and greps.
Here, I have a shell script named load.sh.
It start my program named "demo" with supervise,
When I run it with sh load.sh start | stop, it works well.
However, when I run it with ./load.sh start | stop, it works bad. the demo is frequently started(and exit) by the supervise.
What's the problem of the two ways of running the shell script?
and is there any problem(bug) in the script cause the supervise frequently restart the demo?
Thanks a lot!
#!/bin/bash
cd `dirname $0` || exit
mkdir -p status/demo
dir_name=`pwd`
STR_LIB=${dir_name}/lib
if [ -z "${LD_LIBRARY_PATH}" ]; then
export LD_LIBRARY_PATH="${STR_LIB}"
else
export LD_LIBRARY_PATH="${STR_LIB}:${LD_LIBRARY_PATH}"
fi
start() {
sleep 1
bin/supervise.demo -u status/demo bin/demo >/dev/null 2>&1 &
}
stop() {
if [ -f status/demo/lock ]; then
supervise_demo_pid=`/sbin/fuser status/demo/lock`
`ps -ef | grep "$supervise_demo_pid" | grep "supervise.demo" | grep -v grep > /dev/null 2>&1`
if [ $? -eq 0 ] && [ "$supervise_demo_pid" != "" ] ; then
echo "kill supervise.demo process:"${supervise_demo_pid}
kill -9 $supervise_demo_pid
fi
fi
if [ -f status/demo/status ]; then
demo_pid=`od -An -j16 -N2 -tu2 status/demo/status`
`ps -ef | grep "$demo_pid" | grep "demo" | grep -v grep > /dev/null 2>&1`
if [ $? -eq 0 ]; then
echo "kill demo process:"${demo_pid}
kill -9 $demo_pid
fi
fi
}
case "$1" in
start)
stop
start
echo "Done!"
;;
stop)
stop
echo "Done!"
;;
*)
echo "Usage: $0 {start|stop}"
;;
esac
sh script.sh runs the script in sh, while running it as ./script.sh uses whatever is specified on its first "shebang" line - /bin/bash in this case.
sh and /bin/bash might be different shells, so they interpret the script differently. What sh is depends on your distribution, $PATH, aliases etc.
When you run your script via ./load.sh start | stop it runs with processor that is specified in shebang. In your case it is bash:
#!/bin/bash
What about sh load.sh start | stop. In Ubuntu (by default) sh is actually just a link and in points to dash.
To check it:
$ which sh
/bin/sh
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Mar 16 00:54 /bin/sh -> dash
sh foo will search $path for an executable foo
sh ./foo demands execution from the $cwd
both
foo and ./foo run via the shebang as noted herein
all forms will invoke foo with the perms of the specific file referenced, including suid,guid
I am a shell scripting newbie trying to understand some code, but there are some lines that are too complexe for me. The piece of code I'm talking about can be found here: https://gist.github.com/447191
It's purpose is to start, stop and restart a server. That's pretty standard stuff, so it's worth taking some time to understand it. I commented those lines where I am unsure about the meaning or that I completely don't understand, hoping that somone could give me some explanation.
#!/bin/bash
#
BASE=/tmp
PID=$BASE/app.pid
LOG=$BASE/app.log
ERROR=$BASE/app-error.log
PORT=11211
LISTEN_IP='0.0.0.0'
MEM_SIZE=4
CMD='memcached'
# Does this mean, that the COMMAND variable can adopt different values, depending on
# what is entered as parameter? "memcached" is chosen by default, port, ip address and
# memory size are options, but what is -v?
COMMAND="$CMD -p $PORT -l $LISTEN_IP -m $MEM_SIZE -v"
USR=user
status() {
echo
echo "==== Status"
if [ -f $PID ]
then
echo
echo "Pid file: $( cat $PID ) [$PID]"
echo
# ps -ef: Display uid, pid, parent pid, recent CPU usage, process start time,
# controling tty, elapsed CPU usage, and the associated command of all other processes
# that are owned by other users.
# The rest of this line I don't understand, especially grep -v grep
ps -ef | grep -v grep | grep $( cat $PID )
else
echo
echo "No Pid file"
fi
}
start() {
if [ -f $PID ]
then
echo
echo "Already started. PID: [$( cat $PID )]"
else
echo "==== Start"
# Lock file that indicates that no 2nd instance should be started
touch $PID
# COMMAND is called as background process and ignores SIGHUP signal, writes it's
# output to the LOG file.
if nohup $COMMAND >>$LOG 2>&1 &
# The pid of the last background is saved in the PID file
then echo $! >$PID
echo "Done."
echo "$(date '+%Y-%m-%d %X'): START" >>$LOG
else echo "Error... "
/bin/rm $PID
fi
fi
}
# I don't understand this function :-(
kill_cmd() {
SIGNAL=""; MSG="Killing "
while true
do
LIST=`ps -ef | grep -v grep | grep $CMD | grep -w $USR | awk '{print $2}'`
if [ "$LIST" ]
then
echo; echo "$MSG $LIST" ; echo
echo $LIST | xargs kill $SIGNAL
# Why this sleep command?
sleep 2
SIGNAL="-9" ; MSG="Killing $SIGNAL"
if [ -f $PID ]
then
/bin/rm $PID
fi
else
echo; echo "All killed..." ; echo
break
fi
done
}
stop() {
echo "==== Stop"
if [ -f $PID ]
then
if kill $( cat $PID )
then echo "Done."
echo "$(date '+%Y-%m-%d %X'): STOP" >>$LOG
fi
/bin/rm $PID
kill_cmd
else
echo "No pid file. Already stopped?"
fi
}
case "$1" in
'start')
start
;;
'stop')
stop
;;
'restart')
stop ; echo "Sleeping..."; sleep 1 ;
start
;;
'status')
status
;;
*)
echo
echo "Usage: $0 { start | stop | restart | status }"
echo
exit 1
;;
esac
exit 0
1)
COMMAND="$CMD -p $PORT -l $LISTEN_IP -m $MEM_SIZE -v" — -v in Unix tradition very often is a shortcut for --verbose. All those dollar signs are variable expansion (their text values are inserted into the string assigned to new variable COMMAND).
2)
ps -ef | grep -v grep | grep $( cat $PID ) - it's a pipe: ps redirects its output to grep which outputs to another grep and the end result is printed to the standard output.
grep -v grep means "take all lines that do not contain 'grep'" (grep itself is a process, so you need to exclude it from output of ps). $( $command ) is a way to run command and insert its standard output into this place of script (in this case: cat $PID will show contents of file with name $PID).
3) kill_cmd.
This function is an endless loop trying to kill the LIST of 'memcached' processes' PIDs. First, it tries to send TERM signal (politely asking each process in $LIST to quit, saving its work and shutting down correctly), gives them 2 seconds (sleep 2) to do their shutdown job and then tries to make sure that all processes are killed using signal KILL (-9), which slays the process immediately using OS facilities: if a process has not done its shutdown work in 2 seconds, it's considered hung). If slaying with kill -9 was successful, it removes the PID file and quits the loop.
ps -ef | grep -v grep | grep $CMD | grep -w $USR | awk '{print $2}' prints all PIDs of processes with name $CMD ('memcached') and user $USR ('user'). -w option of grep means 'the Whole word only' (this excludes situations where the sought name is a part of another process name, like 'fakememcached'). awk is a little interpreter most often used to take a word number N from every line of input (you can consider it a selector for a column of a text table). In this case, it prints every second word in ps output lines, that means every PID.
If you have any other questions, I'll add answers below.
Here is an explanation of the pieces of code you do not understand:
1.
# Does this mean, that the COMMAND variable can adopt different values, depending on
# what is entered as parameter? "memcached" is chosen by default, port, ip address and
# memory size are options, but what is -v?
COMMAND="$CMD -p $PORT -l $LISTEN_IP -m $MEM_SIZE -v"
In the man, near -v:
$ man memcached
...
-v Be verbose during the event loop; print out errors and warnings.
...
2.
# ps -ef: Display uid, pid, parent pid, recent CPU usage, process start time,
# controling tty, elapsed CPU usage, and the associated command of all other processes
# that are owned by other users.
# The rest of this line I don't understand, especially grep -v grep
ps -ef | grep -v grep | grep $( cat $PID )
Print all processes details (ps -ef), exclude the line with grep (grep -v grep) (since you are running grep it will display itself in the process list) and filter by the text found in the file named $PID (/tmp/app.pid) (grep $( cat $PID )).
3.
# I don't understand this function :-(
kill_cmd() {
SIGNAL=""; MSG="Killing "
while true
do
## create a list with all the pid numbers filtered by command (memcached) and user ($USR)
LIST=`ps -ef | grep -v grep | grep $CMD | grep -w $USR | awk '{print $2}'`
## if $LIST is not empty... proceed
if [ "$LIST" ]
then
echo; echo "$MSG $LIST" ; echo
## kill all the processes in the $LIST (xargs will get the list from the pipe and put it at the end of the kill command; something like this < kill $SIGNAL $LIST > )
echo $LIST | xargs kill $SIGNAL
# Why this sleep command?
## some processes might take one or two seconds to perish
sleep 2
SIGNAL="-9" ; MSG="Killing $SIGNAL"
## if the file $PID still exists, delete it
if [ -f $PID ]
then
/bin/rm $PID
fi
## if list is empty
else
echo; echo "All killed..." ; echo
## get out of the while loop
break
fi
done
}
This function will kill all the processes related to memcached slowly and painfully (actually quite the opposite).
Above are the explanations.
I have a shell script like this.
line="$#" # get the complete first line which is the complete script path
name_of_file = ${line%.*}
file_extension = ${line##*.}
if [ $file_extension == "php"]
then
ps aux | grep -v grep | grep -q "$line" || ( nohup php -f "$line" > /var/log/iphorex/$name_of_file.log & )
fi
if [ $file_extension == "java"]
then
ps aux | grep -v grep | grep -q "$line" || ( nohup java -f "$name_of_file" > /var/log/iphorex/$name_of_file.log & )
fi
here line variable has values like /var/www/dir/myphp.php or /var/www/dir/myjava.java.
The purpose of shell script is to check if these processes are already running and if not i try to run them.I get the following errors.
name_of_file: command not found
file_extension: command not found
[: missing `]'
[: missing `]'
Any ideas?
Firstly, the shell processor treats the line:
name_of_file = ${line%.*}
as the execution of the command:
name_of_file
with the parameters:
= ${line%.*}
you need to write it as:
name_of_file=${line%.*}
This makes it into a variable=value. You need to repeat this for the file_extension = line as well.
Secondly, the if:
if [ $file_extension == "php"]
has exactly the same parsing problem, you must have a space before the trailing ], because otherwise the parser thinks you're checking if $file_extension is equal to the string: "php]"
if [ $file_extension == "php" ]
delete the spaces first, maybe this will help...
name_of_file=${line%.*}
file_extension=${line##*.}
EDIT
Try this:
if [ $file_extension="php" ]
..
if [ $file_extension="java" ]
The other answers are right that the problem in your script lies in stray spaces in your variable assignments and [ .. ] statements.
(off-topic. FYI)
I took the liberty of refactoring your script (untested!) just to highlight some alternatives, namely:
using pgrep instead of ps aux | grep .....
using case
-
#!/bin/bash
line="$#" # get the complete first line which is the complete script path
name_of_file=${line%.*}
pgrep "$line" > /dev/null && exit # exit if process running
case "${line##*.}" in # check file extension
php)
nohup php -f "$line" > /var/log/iphorex/$name_of_file.log &
;;
java)
nohup java -f "$name_of_file" > /var/log/iphorex/$name_of_file.log &
;;
esac