Strange behavior returning incorrect count

On AIX When I Run the commands below I get -

cat tt11.ksh

#!/bin/ksh
ps -eaf |grep tt11.ksh|grep -v grep|wc -l
count=`ps -eaf |grep tt11.ksh|grep -v grep|wc -l`
echo "value of count is $count"
 

Output (what I expected)

 ./tt11.ksh
       1
value of count is        1

When I Run the same program (tt11.ksh) on Redhat Linux Version 5. I get

 ./tt11.ksh
1
value of count is 2

Any Idea why that would be?

Different versions / implementations of shells handling subshells differently. Every pipe makes a copy of the process then runs exec to run the command you wanted. So the count isn't incorrect, exactly.

To debug this, run without the wc -l

#!/bin/ksh
ps -eaf |grep tt11.ksh|grep -v grep
count=`ps -eaf |grep tt11.ksh|grep -v grep`
echo ""
echo "$count"
echo "----"

change your grep to use a regexp to search so that the search doesn't match itself. Otherwise you may see two matches... one for the process you wanted and one for your grep itself. It will vary from system to system and in some cases can vary on the same system.

e.g.
Instead of

grep ttll.ksh

change it to

grep 'ttll\.ksh'
cat tt11.ksh
#!/bin/ksh
ps -eaf |grep tt11.ksh|grep -v grep
count=`ps -eaf |grep tt11.ksh|grep -v grep`
echo ""
echo "$count"
echo "----"

[itmuser@njctivtemspr01 scripts]$ ./tt11.ksh
itmuser  24550 18489  0 13:20 pts/0    00:00:00 /bin/ksh ./tt11.ksh
 
itmuser  24550 18489  0 13:20 pts/0    00:00:00 /bin/ksh ./tt11.ksh
itmuser  24556 24550  0 13:20 pts/0    00:00:00 /bin/ksh ./tt11.ksh

----

Looks like parent shell is creating new shell to run the command. Is there a way to avoid this? Goal is to have same code to run on AIX and Linux ksh shell.

That is how pipes work.

To keep the forums high quality for all users, please take the time to format your posts correctly.

First of all, use Code Tags when you post any code or data samples so others can easily read your code. You can easily do this by highlighting your code and then clicking on the # in the editing menu. (You can also type code tags

```text
 and 
```

by hand.)

Second, avoid adding color or different fonts and font size to your posts. Selective use of color to highlight a single word or phrase can be useful at times, but using color, in general, makes the forums harder to read, especially bright colors like red.

Third, be careful when you cut-and-paste, edit any odd characters and make sure all links are working property.

Thank You.

The UNIX and Linux Forums

I tried it, it does not make any difference.

The traditional way for a process to prevent multiple instances of itself is to create a lockfile, not ps | awk | sed | cut | grep | kitchen | sink.

Is it possible for you to do it as

cat tt11.ksh

#!/bin/ksh
ps | grep -c tt11.ksh
count=$(ps | grep -c tt11.ksh)
echo "value of count is $count"

In RHEL6

./tt11.ksh
1
value of count is 1

Tried it does not work in RHEL 5.

As said earlier, pipes do a fork/exec. And while the exec is not yet ready there is a cloned shell. This is a race condition.
To avoid the race conditions you must avoid sub-shells and pipes and maybe even calling external programs.
The best thing is pgrep . Unfortunately AIX does not have it.
cjcox and Aia solutions combined is maybe good enough:

!/bin/ksh
ps | grep -c "tt11[.]ksh"
count=$(ps | grep -c "tt11[.]ksh")
echo ""
echo "$count"
echo "----"

--
Someone mentioned the lockfile method.
If the purpose is to prevent multiple instances to run, then indeed the lockfile method seems better than the process method.

It's not that it "doesn't work". It's that every time you use a | or backticks, you're telling the shell to create new processes.

If you want a way to check if an instance of your process is running without using ps, I suggest a more traditional lock file.