* [PATCH] zshbuiltins(1): Document 'which''s "not found is not an error" behaviour.
2018-09-24 12:51 ` Peter Stephenson
@ 2018-09-24 13:22 ` Daniel Shahaf
2018-09-24 22:18 ` BUG: Shell builtin `which` prints non-existent commands to stdout Stephane Chazelas
2018-09-24 22:32 ` Stephane Chazelas
2 siblings, 0 replies; 10+ messages in thread
From: Daniel Shahaf @ 2018-09-24 13:22 UTC (permalink / raw)
To: zsh-workers
---
Doc/Zsh/builtins.yo | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 76b593fd2..0141305b4 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -2373,6 +2373,12 @@ item(tt(whence) [ tt(-vcwfpamsS) ] [ tt(-x) var(num) ] var(name) ...)(
For each var(name), indicate how it would be interpreted if used as a
command name.
+If var(name) is not an alias, built-in command, external command, shell
+function, hashed command, or a reserved word, the exit status shall be
+non-zero, and DASH()- if tt(-v), tt(-c), or tt(-w) was passed DASH()- a message
+will be written to standard output. (This is different from other shells that
+write that message to standard error.)
+
tt(whence) is most useful when var(name) is only the last path component
of a command, i.e. does not include a `tt(/)'; in particular, pattern
matching only succeeds if just the non-directory component of the command is
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: BUG: Shell builtin `which` prints non-existent commands to stdout
2018-09-24 12:51 ` Peter Stephenson
2018-09-24 13:22 ` [PATCH] zshbuiltins(1): Document 'which''s "not found is not an error" behaviour Daniel Shahaf
@ 2018-09-24 22:18 ` Stephane Chazelas
2018-09-25 7:56 ` Stephane Chazelas
2018-09-24 22:32 ` Stephane Chazelas
2 siblings, 1 reply; 10+ messages in thread
From: Stephane Chazelas @ 2018-09-24 22:18 UTC (permalink / raw)
To: Peter Stephenson; +Cc: Zsh Workers
2018-09-24 13:51:24 +0100, Peter Stephenson:
> On Mon, 24 Sep 2018 14:29:33 +0200
[...]
> + The original reason for this is that this behaviour is inherited
> + from the C shell (csh), where `tt(which)' itself orignated. So
> + it has been in zsh a very long time, and it is now a feature.
> + (It would be possible to change this in emulation modes; however.
> + so far this possibility has been seen has more of an additional
> + confusion than a help.)
[...]
csh had no "which" (tcsh has a which builtin), but there was a
"which" csh script added to 3BSD 1980 that was looking up
commands in $PATH and in the aliases defined through ~/.cshrc.
https://github.com/dspinellis/unix-history-repo/blob/BSD-3/usr/ucb/which
There's no easy way to write something to stderr in csh, so it's
not surprising that that script didn't.
In any case, the "command not found" can be seen as the normal
output of which, it is *the* information that it is returning
for that command.
zsh is not the only shell for which "type not-a-command" doesn't
output "command not found" on stderr. The Bourne shell, pdksh
and derivatives and ash-based shells do as well.
--
Stephane
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: BUG: Shell builtin `which` prints non-existent commands to stdout
2018-09-24 22:18 ` BUG: Shell builtin `which` prints non-existent commands to stdout Stephane Chazelas
@ 2018-09-25 7:56 ` Stephane Chazelas
0 siblings, 0 replies; 10+ messages in thread
From: Stephane Chazelas @ 2018-09-25 7:56 UTC (permalink / raw)
To: Peter Stephenson, Zsh Workers
2018-09-24 23:18:20 +0100, Stephane Chazelas:
> 2018-09-24 13:51:24 +0100, Peter Stephenson:
> > On Mon, 24 Sep 2018 14:29:33 +0200
> [...]
> > + The original reason for this is that this behaviour is inherited
> > + from the C shell (csh), where `tt(which)' itself orignated. So
> > + it has been in zsh a very long time, and it is now a feature.
> > + (It would be possible to change this in emulation modes; however.
> > + so far this possibility has been seen has more of an additional
> > + confusion than a help.)
> [...]
>
> csh had no "which" (tcsh has a which builtin), but there was a
> "which" csh script added to 3BSD 1980 that was looking up
> commands in $PATH and in the aliases defined through ~/.cshrc.
> https://github.com/dspinellis/unix-history-repo/blob/BSD-3/usr/ucb/which
[...]
Sorry, correction: "which" was added to csh in 4.4BSD (1991) and
various other BSDs that had already forked by then later (NetBSD
in 1994 for instance, and FreeBSD has switched to tcsh IIRC),
though csh on some systems like Solaris are based on older
versions and still don't have "which" builtin.
--
Stephane
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: BUG: Shell builtin `which` prints non-existent commands to stdout
2018-09-24 12:51 ` Peter Stephenson
2018-09-24 13:22 ` [PATCH] zshbuiltins(1): Document 'which''s "not found is not an error" behaviour Daniel Shahaf
2018-09-24 22:18 ` BUG: Shell builtin `which` prints non-existent commands to stdout Stephane Chazelas
@ 2018-09-24 22:32 ` Stephane Chazelas
2018-09-25 9:10 ` Peter Stephenson
2 siblings, 1 reply; 10+ messages in thread
From: Stephane Chazelas @ 2018-09-24 22:32 UTC (permalink / raw)
To: Peter Stephenson; +Cc: Zsh Workers
2018-09-24 13:51:24 +0100, Peter Stephenson:
> On Mon, 24 Sep 2018 14:29:33 +0200
[...]
> + The issue is that if you run:
> + verb(
> + which non-existent-command
> + )
> + the error message goes, unusually, to standard output rather than
> + to standard error. Other shells send this message to standard error,
> + as they would if the command was about to be executed but could not be
> + found.
[...]
About "other shells" above, AFAIK, tcsh is the only other shell
that has a "which" builtin and it does also send "command not
found" to stdout. So zsh behaves like every other shells in that
regard.
To phrase my last comment differently, there are also a variety
of "which" command implementations outside of any shell, the
first of which (which appeared in 3BSD) was primarily intended
for csh users (as it read your ~/.cshrc for aliases) and was
written as a csh script that did also send the "command not
found" to stdout.
That's also the one still found on many commercial Unices.
There is also a GNU "which" command (which tries to generalise
what that csh script did for other shells) and sends the
command-not-found to stderr.
Debian has a POSIX sh which script that doesn't output any
command-not-found error and doesn't look-up aliases of any
shell (it writes the usage message on stdout followed by the
"illegal option" on stderr).
BSDs which has now been merged with whereis and been rewritten in
C and no longer looks up your csh aliases and like the Debian
script doesn't output any command-not-found error.
See also
https://unix.stackexchange.com/questions/85249/why-not-use-which-what-to-use-then
--
Stephane
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: BUG: Shell builtin `which` prints non-existent commands to stdout
2018-09-24 22:32 ` Stephane Chazelas
@ 2018-09-25 9:10 ` Peter Stephenson
0 siblings, 0 replies; 10+ messages in thread
From: Peter Stephenson @ 2018-09-25 9:10 UTC (permalink / raw)
To: Zsh Workers
On Mon, 24 Sep 2018 23:32:53 +0100
Stephane Chazelas <stephane.chazelas@gmail.com> wrote:
> About "other shells" above, AFAIK, tcsh is the only other shell
> that has a "which" builtin and it does also send "command not
> found" to stdout. So zsh behaves like every other shells in that
> regard.
Thanks, I've updated the text.
pws
diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index 9f634d1..81d7628 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -1976,21 +1976,22 @@ sect(Why does `which' output for missing commands go to stdout?)
as they would if the command was about to be executed but could not be
found.
- The original reason for this is that this behaviour is inherited
- from the C shell (csh), where `tt(which)' itself originated. So
- it has been in zsh a very long time, and it is now a feature.
- (It would be possible to change this in emulation modes; however.
- so far this possibility has been seen has more of an additional
- confusion than a help.)
-
- If you want some further rationalisation, which may be what the C
- shell designers had in mind, you might note that `tt(which)' is
- designed as a way of outputting information about a command. So
- `this command can be found in ...' and `this command can't be found'
- are both bits of information here, unlike the case where the command
- is to be executed. So although it differs from other Bourne-style
- shells it is in fact self-consistent. Note that the exit status does
- reflect the fact the command can't be found.
+ The original reason for this is that this behaviour is inherited from
+ previous versions of `tt(which)', a builtin in tcsh (an adaptation of
+ the C Shell with better editing) and also a separate script. Other
+ shells had equivalent commands, `tt(whence)' and `tt(type), that zsh
+ has also adopted. So in fact this has always been a feature of
+ `tt(which)'. (It would be possible to change this in emulation modes;
+ however. so far this possibility has been seen has more of an
+ additional confusion than a help.)
+
+ If you want some further rationalisation, you might note that
+ `tt(which)' is designed as a way of outputting information about a
+ command. So `this command can be found in ...' and `this command
+ can't be found' are both bits of information here, unlike the case
+ where the command is to be executed. So although it differs from
+ other Bourne-style shells it is in fact self-consistent. Note that
+ the exit status does reflect the fact the command can't be found.
chapter(The mysteries of completion)
^ permalink raw reply [flat|nested] 10+ messages in thread