
csh/tchs: odd behaviour on prog | grep -q string
Our site has a legacy of old csh scripts. A recent change broke
some of them. Investigating it shows (what to me is) a very odd
behavior of csh and tcsh.
Problem:
We want to set $status depending on whether program "prog" produces
output "string" or not. Using gnu grep several scripts used
prog | grep -q string
This construct works as I expected under sh, bash and zsh.
However, running this in the csh or tcsh I find that
- if the string is NOT found, $status is set to 1 -- as expected
- if the string IS found, $status is set to the return status of
prog, not to 0 (the status of grep).
In other words, it does NOT produce the same affect as
prog > TEMP
grep -q string TEMP
That would be one work-around, but to be clean we have to delete TEMP
without disturbing the status. This can be done, but since the
construct appears a lot I was looking for a simple change.
Enclosing it in parentheses, like this:
( prog | string -q string )
seemed to work, but I don't know if I can rely on it. I couldn't find
a definitive answer in either the csh man page nor "The Unix C Shell
Field Guide".
------------------------------------------------------------------------
Here's some examples of what I mean.
y and n echo yes and no respectively and exit with 101 and 99:
% cat y
#! /bin/sh
echo yes
exit 101
% cat n
#! /bin/sh
echo no
exit 99
% ./y
yes
% echo $status
101
% ./n
no
% echo $status
99
%
The next 2 cases produce "strange" results; the rest seem reasonable:
% ./n | grep -q no
% echo $status
99
% ./y | grep -q yes
% echo $status
101
% ./y | grep -q no
% echo $status
1
% ./n | grep -q yes
% echo $status
1
% ( ./n | grep -q no )
% echo $status
0
% ( ./n | grep -q yes )
% echo $status
1
%
------------------------------------------------------------------------
We got around the problem in some other way in the end, but I'm
curious to know why it happens, and if enclosing the construct in
parentheses is a reliable way to make it produce the "expected" [to me!]
result.
Richard Sharman