zsh-users
 help / color / mirror / code / Atom feed
* nomatch/cshnullglob problems
@ 2006-03-30 23:02 Michael Wardle
  0 siblings, 0 replies; 3+ messages in thread
From: Michael Wardle @ 2006-03-30 23:02 UTC (permalink / raw)
  To: zsh-users

Hi

There's a couple of things about the NO_MATCH and CSH_NULL_GLOB options
that have surprised me.

It seems that sometimes, CSH_NULL_GLOB causes an error even if some of
the file names in the list match.  It also seems that such an error is
fatal when using "source" or "." (dot).

If I create a script called "globtest" with the following contents,
-----
#!/bin/zsh

setopt cshnullglob
unsetopt nomatch
echo start
for dir
in /opt/*/bin /usr/X11R6/bin /usr/kerberos/bin /usr/posix/bin /usr/gnu/bin /usr/local/bin "$HOME"/bin
do
    test -d "$dir" && echo "$dir"
done
echo finish
-----

set it executable, then run "./globtest", I get the following output:
-----
start
globtest:6: no match
finish
-----

According to the manual:
	CSH_NULL_GLOB <C>
		If a pattern for filename generation has no matches, delete the
pattern
		from the argument list; do not report an error unless all the patterns
in
		a command have no matches.  Overrides NOMATCH.

I this case, I would expect the output to be the same as when the third
line is changed to "unsetopt cshnullglob":
-----
start
/usr/X11R6/bin
/usr/local/bin
/home/michael/bin
finish
-----

since the non-matching "/opt/*/bin" should be removed from the list,
leaving /usr/X11R6/bin /usr/kerberos/bin, etc., and no error should be
reported.

The same directory list containing the /opt/*/bin wildcard seems to work
fine in tcsh, which the CSH_NULL_GLOB option should be emulating.

If the option only comes into effect if there are multiple wildcards
(globbing characters) in the same list, then what is its use, and how
can I get the result I want?

Further, if I run ". globtest", I get the following output:
-----
start
globtest:6: no match
-----

which suggests that the "." command terminates as soon as an error is
encountered.

If I add a "set -o | grep err", I can see that neither ERR_EXIT nor
ERR_RETURN are set, so I would have expected the sourcing of the script
to complete and print "finish" like when it's run as a script.  (The
same script does complete and print "finish" when sourcing the script in
bash.)

I'm running zsh 4.2.5 on Ubuntu Linux.

Is this a bug or the expected behavior?

Thanks

Michael


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: nomatch/cshnullglob problems
@ 2006-03-31 11:23 Michael Wardle
  0 siblings, 0 replies; 3+ messages in thread
From: Michael Wardle @ 2006-03-31 11:23 UTC (permalink / raw)
  To: zsh-users

Hi Bart

Thanks for your explanations.

The script is being used in bash and zsh, and I'd rather not introduce
any Z shellisms such as the (D) qualifier.  When I run the script
normally, it is inside an "emulate -L ksh", so there's no big problem.
I think adding a dummy wildcard to the list might be the simplest
workaround.

Would you believe I had set "nonomatch" in tcsh, so tcsh was in a sense
emulating ksh, while zsh was emulating csh!  (This explains why I wasn't
getting an error with the equivalent foreach loop in tcsh.)

"Fatal" was the best short way I could think of describing the
behavior. :-)

Under what circumstances should sourcing of a script short-circuit?  A
very simple script such as:
-----
echo start
false
echo finish
-----

echoes "finish" and runs to completion when sourced, yet:
-----
echo start
echo /nosuchfile*
echo finish
-----

exits before echoing "finish".

It seems to be only if a pattern fails, which doesn't seem all that
useful!  It's also disappointing that bash and zsh differ in this
respect.

Can I suggest a simple patch to the manual such as the following:
--- builtins.yo 20 Mar 2006 11:06:24 -0000      1.84
+++ builtins.yo 31 Mar 2006 11:04:47 -0000
@@ -48,6 +48,9 @@
 they become the positional parameters; the old positional
 parameters are restored when the var(file) is done executing.
 The exit status is the exit status of the last command executed.
+
+If an error occurs due to a non-matching filename glob, the tt(.)
command returns
+to the shell and no further commands from var(file) are executed.
 )
 findex(NOTRANS(:))
 cindex(expanding parameters)

I hope the mark-up is correct.  I don't speak YODL. :-)

Thanks

Michael


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: nomatch/cshnullglob problems
@ 2006-03-31  9:52 Bart Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2006-03-31  9:52 UTC (permalink / raw)
  To: zsh-users

On Mar 31, 10:02am, Michael Wardle wrote:
}
} It seems that sometimes, CSH_NULL_GLOB causes an error even if some of
} the file names in the list match.
[...]
} According to the manual:
}  CSH_NULL_GLOB <C>
}   If a pattern for filename generation has no matches, delete the
}   pattern from the argument list; do not report an error unless all
}   the patterns in a command have no matches. Overrides NOMATCH.

Right:  Do not report an error unless all the PATTERNS have no matches.
There is exactly one pattern in your sample command (/opt/*/bin), and
it has no matches.  Any other argument strings with no wildcards in them
are not patterns; the shell doesn't test, or care, whether they "match"
anything.  

} It also seems that such an error is fatal when using "source" or "."
} (dot).

It's not "fatal" or the whole shell would exit ...

} If I add a "set -o | grep err", I can see that neither ERR_EXIT nor
} ERR_RETURN are set, so I would have expected the sourcing of the script
} to complete and print "finish" like when it's run as a script.

This is another case where zsh behaves like csh. If you try this same
thing in tcsh, you'll find a "source"d file stops at the same point.
This behavior is considered more useful because, e.g., it prevents
unexepcted commands from being executed from startup files in the event
of an error in setting up a conditional.

Apparently this never made it into the zsh manual because (at the time,
when 4.x BSD and csh were widely in use and zsh users were more often 
switch form csh than from a Bourne-like shell) it's such a well-known
csh behavior.  

} The same directory list containing the /opt/*/bin wildcard seems to
} work fine in tcsh, which the CSH_NULL_GLOB option should be emulating.

Really?  Here's tcsh on my system:

[schaefer@torch ~]$ foreach x (/opt/*/bin /usr/X11R6/bin /usr/kerberos/bin
/usr/posix/bin /usr/gnu/bin /usr/local/bin "$HOME"/bin)
foreach: No match.
[schaefer@torch ~]$ foreach x ( /opt/*/bin /usr/X*6/bin /usr/kerberos/bin
/usr/posix/bin /usr/gnu/bin /usr/local/bin "$HOME"/bin )
foreach? end
[schaefer@torch ~]$ 

Note it works if there are two patterns, one of which doesn't match.

} If the option only comes into effect if there are multiple wildcards
} (globbing characters) in the same list, then what is its use, and how
} can I get the result I want?

In your specific example, you probably want just plain NULL_GLOB, which
you can turn on for a single pattern thusly:

for dir
in /opt/*/bin(N) /usr/X11R6/bin /usr/kerberos/bin \
   /usr/posix/bin /usr/gnu/bin /usr/local/bin "$HOME"/bin


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-03-31 11:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-30 23:02 nomatch/cshnullglob problems Michael Wardle
2006-03-31  9:52 Bart Schaefer
2006-03-31 11:23 Michael Wardle

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).