Comparing multiple variable in if statement

Hi there

this script is an atempt to define which instances of Jboss relate to its PID by the date and timestamp I am using calc to test with. On our system the only way you can tell which instance relates to a particular instance is by looking at the start up time and date in a log.

The problem I am having is that if [ "$inst1" == "$proc$val" ] needs to compare with $proc0 the first time the loop runs, $pro1 the next and $proc3 finally in my case. This needs to increment in this way as in theory you could have varying instances of JBoss or calc in this case running.

Can any one point me in the right direction?

 
#note inst1 and 2 would normally be pulled from pgrep
inst1="09:21"
inst2="11:40"
#pull in the current running instances of gcalctool
PID1=`pgrep -f "gcalctool"`
set -A array $PID1
echo 'Current number of calc running processes : '${#array
[*]}
# // print number values in array
#Cycle through processes and get the timestamp for each process match to Jboss instance
val=0
for i in {1..${#array
[*]}}
do
        eval "proc$val=\"`ls -ld /proc/${array[$val]} |awk '{print$7}'`\""       
        if [ "$inst1" == "$proc$val" ]
                then
                        echo 'killing '${array[0]}' will shutdown the Jboss Instance for Efin live'
                fi
((val++))
done
echo $proc0 $proc1 $proc2 $tmp
unset array
 

What shell is this? You may be able to use more graceful, safe, and simple things than eval in shells better than a generic bourne.

Hi there

Its running in ksh, is it possible to do what I am asking?

cheers

In BASH and KSH you can do things like:

VARNAME="$proc$val"
echo "value of ${VARNAME} is ${!VARNAME}"

Also, you can avoid the eval by feeding the variable name into read:

... | read "$proc$val"

Note that this won't work right in other shells, because the 'read' will end up in a subshell. KSH orders pipes in reverse for this reason.

Also, why run ls 99 times instead of 1? You can do everything in one whack, and move the equality inside awk itself:

pushd /proc
PIDS=$(ls -ld ${array[*]} | awk -v INST="$inst1" '$7 == INST { print $NF }')
popd

echo $PIDS

Generating a simple list without the need for dynamic variables inside the shell.

If your needs are more complex than they appear -- do you need to compare inst2 as well? -- explain and I'll add it.

1 Like

On the inst yes it needs to compare, you see when Jboss starts it writes a new log file with the date and timestamp when its was started.

If we can compare these with the PID date and time then we can detremine if it was TEST DEV or Live and which PID to kill.

here is my script in progress (no laughing please I don't do scripting enough to warrant a good understanding) :slight_smile: its work in progress!

 
#!/usr/bin/ksh
#NHA April 2012
echo 'The current Efin solution runs six instances of JBoss :  efin|live efin|test cp|live cp|test eproc|live eproc|test'
echo
#efin live | test  INSTANCES
#inst1=`ls -ltr /cedar/efin/v40/jboss/live/efin/coa/JBoss_4_2_3/server/coa/log/boot.log | awk ' {print $6,$7,$8}'`
#inst2=`ls -ltr /cedar/efin/v40/jboss/test/efin/coa/JBoss_4_2_3/server/coa/log/boot.log |  awk ' {print $6,$7,$8}'`
inst1="09:21"
inst2="11:40"
#pull in the current running instances of Jboss
PID1=`pgrep -f "gcalctool"`
set -A array $PID1
echo 'Current number of calc running processes : '${#array
[*]}
# // print number values in array
#Cycle through processes and get the timestamp for each process match to Jboss instance
val=0
for i in {1..${#array
[*]}}
do
        eval "proc$val=\"`ls -ld /proc/${array[$val]} |awk '{print $7}'`\""
        tmp=$proc$val
        echo $tmp
        if [ "$inst1" == "$proc$val" ]
                then
                        echo 'killing '${array[0]}' will shutdown the Jboss Instance for Efin live'
                fi
((val++))
done
echo $proc0 $proc1 $proc2 $tmp
unset array
~
 

I'd handle it as a stream instead of using arrays and dynamic variable names. xargs can be used to attach the stream of one program to the arguments of another to make things happen in even fewer shell steps. Much more straightforward.

I'd like to see what the output for pgrep -f "gcalctool" and cd /proc ; ls -ld somepid looks like for your system or I may get this somewhat wrong.

# pushd is like cd but with memory.  'popd' to return where you started.  It can nest, too.
pushd /proc

# Get the PID's, run ls -ld pid1 pid2 ..., feed it into awk, which will hunt for matching start-times and print the relevant PID's and what they belong to.
pgrep -f "gcalctool" | xargs ls -ld | awk 'BEGIN { A[live]="live"; A[test]="test" }; $7 in A { print $NF, $7, A[$7] }' live="09:21" test="11:40" |
while read PID TIME WHICH
do
        echo "$PID is $WHICH"
done

popd

Should show multiple lines like '123456 is live'.

Hi there

Thank you for the help on this one, This is the output you requested

$ pgrep -f "gcalctool"
9467
9486
13903
$ cd /proc
$ ls -ld 9467
dr-xr-xr-x 8 nathan nathan 0 2012-05-04 09:20 9467
$ ls -ld 9486
dr-xr-xr-x 8 nathan nathan 0 2012-05-04 09:20 9486

I also ran the script in ksh and got

$ ./calc2.sh
./calc2.sh[4]: pushd: not found [No such file or directory]
ls: cannot access 9467: No such file or directory
ls: cannot access 9486: No such file or directory
ls: cannot access 13903: No such file or directory
./calc2.sh: line 13: popd: not found

In the meantime I'll do some digging on those commands there new to me so sorry to appear lazy. Its not clicking just yet...

:confused:

AFAIK, pushd and popd are bash only.

--edit--

I found popd and pushed as functions in /usr/local/share/ksh/pushd, that could be sourced into a script. This is with version ksh93t+. Perhaps they are also available on your system.

Use cd /proc instead, then, and then cd back to wherever you started after.