Re: Bash handling of ENOENT on missing files and directories

2017-10-08 Thread PePa

On 10/09/2017 05:30 AM, Jonny Grant wrote:
Fair enough. I agree it has been around for longer, but meant that POSIX 
standardized on that limitation, and didn't offer a better solution that 
clarified, eg ENOENTF ENOENTD


I'm guessing not making the distinction saved a bit of CPU.

yes, a clearer errno value, for files, and separate for directories 
would be ideal.


Would have been better.


Has anyone ever wanted to "cd" into a file?


$ cd file
-bash: cd: file: Not a directory

In this case it tested whether 'file' is a directory. When trying 'cd' 
into 'missingdir', the result is that an entry 'missingdir' couldn't be 
found, whether file or directory. This is actually more informative.


Peter



Re: Bash handling of ENOENT on missing files and directories

2017-10-08 Thread Jonny Grant

Hello Bob
Thank you for your reply

On 15/09/17 02:57, Bob Proulx wrote:

Jonny Grant wrote:

Please keep my email address in any replies

Bob Proulx wrote:

Jonny Grant wrote:

Yes, it's a known limitation of POSIX that it uses a shared error code for
both files and directors, ENOENT. Which without programmers handling and
checking the stat() flags, means the error isn't completely clear in the
case where a file or dir does exist.


I don't see how POSIX is involved in this.  Blaming POSIX is a
complete non-sequitur here.


Why do you feel it isn't?


The "No such file or directory" message I see in the Unix v7 code
circa 1979 and therefore appeared at least that early but probably was
there since the beginning.  That predates the first POSIX standard by
many years.

File errlst.c:
char*sys_errlist[] = {
"Error 0",
"Not owner",
"No such file or directory",
 ...

File errno.h:
#define ENOENT  2


Fair enough. I agree it has been around for longer, but meant that POSIX 
standardized on that limitation, and didn't offer a better solution that 
clarified, eg ENOENTF ENOENTD





I imagine we have spoken already for longer about this, than it would have
been to fix it.


I see no bug to fix here.  However I fear that trying to fix an
imaginary one would introduce a bug here.


How can an easy update to clarify message "No such file or directory"
introduce a bug?


Because "No such file or directory" is the exact error message that
corresponds to the error returned by the OS kernel as defined by the
system in the /usr/include definition file which is used by all
programs.  It is an important commonality.  All programs should say
the same thing for that error.


yes, a clearer errno value, for files, and separate for directories 
would be ideal.




If every program created a different error message for that error then
it would be hard to learn what each and every program said for each
and every individual possible error.  OMG!  That would be horrible.
Changing it to make it something different would obscure the error
that is being returned by the OS.  It would make this one program say
something different for that error than other programs.  Different
makes it harder to understand.


Most programs already use their own messages. eg GEdit :-
Could not find the file “/home/jonny/env.txt”.
Please check that you typed the location correctly and try again.
[Retry] [Cancel]



Let's look at your cases again.


$ cd missingdir
bash: cd: missingdir: No such file or directory


Why do you think that is undesirable?  That is the system error.  The
requested "missingdir" to change directory to failed because there is
no entry by that name, uh, no such file or directory by that name. :-)


Has anyone ever wanted to "cd" into a file?


Likewise, software that deals with directories, or in the case of
"cd" in bash, trying to change directory, can very easily report "No
such directory"


I think some of the problem might be that you are thinking that
directories are not files.  But in Unix like systems everything is a
file.  (And in a Linux like system everything is a file system.  It's
a joke but also with some truth to it.)


yes, I know directories are a kind of special file, but from a user's 
perspective, nowadays they are just folders.



If I were writing that error message I may have said "No such entry"
since that is the literal error.  Meaning directory entry.  But I
could see having written "No such file", stopped there without the
directory hint, and defended it as being correct because everything is
a file.  But I forgive them for helping the user out a little by
hinting that no files, not even special files such as directories,
were found.  Directories are files.  They are special files.  But
files just the same.

   https://en.wikipedia.org/wiki/Unix_file_types
   "The most common special file is the directory."

Let's try some other shells to see what error messages they produce.

$ ksh
$ cd nonexistent
ksh: cd: nonexistent: [No such file or directory]

$ mksh
$ cd nonexistent
mksh: cd: /home/rwp/nonexistent: No such file or directory
$ ^D

$ zsh
% cd nonexistent
cd: no such file or directory: nonexistent

$ csh
% cd nonexistent
nonexistent: No such file or directory.
% exit

We can also try a programming solution too just to double check what
error message is provided using a one-liner.

   $ perl -e 'chdir("doesnotexist") or die "$!\n";'
   No such file or directory

It is good that everyone uses the same error messages.

Let's look at your other case.


$ ./main
-bash: ./main: No such file or directory


$ ksh
$ ./nonexistent
ksh: ./nonexistent: not found [No such file or directory]

$ mksh
$ ./nonexistent
mksh: ./nonexistent: not found
$

$ zsh
% ./nonexistent
zsh: no such file or directory: ./nonexistent
%

$ csh
% ./non-existent
./non-existent: Command not found.
% exit

It looks like mksh and csh are the odd ones out here.


They are both clearer. Like you say "No 

Re: command_not_found_handle documentation omission

2017-10-08 Thread Eduardo A . Bustamante López
On Sun, Oct 08, 2017 at 11:16:33AM -0500, Dan Douglas wrote:
[...]
> Thinking out loud some more... it does make sense that a user in an
> interactive session expects commands to not alter their shell environment,
> and a badly written command_not_found_handle could do that, possibly
> without the user's knowledge on systems that put a handler in a global
> bashrc (likely the most common scenario).
> 
> On the other hand a user that actually defines their own handler could
> have a million reasons to want to propagate some effect to the interactive
> process, e.g. defining an alias or altering PS1. Same for non-interactive
> scripts.
> 

I guess that instead of changing the semantics of
command_not_found_handle, a new special trap could be added that
executes in the context of the shell performing the command lookup.

Although I'm not sure how valuable it would be (the added complexity).
Are there any serious uses of the command_not_found_handle aside from
suggestions during interactive use?



Re: command_not_found_handle documentation omission

2017-10-08 Thread Dan Douglas
On 10/08/2017 10:41 AM, Dan Douglas wrote:
> On 10/08/2017 09:47 AM, Chet Ramey wrote:
>> It was originally intended to take the place of the error message that
>> bash prints when it can't find a program to execute. That message was
>> printed by the subshell forked to execute the command, so the message could
>> be redirected (nearly ll shells do it that way). If you're going to run a
>> command, you run it in the same context as the error message.
> 
> Bash does PATH resolution prior to forking any subshell and no fork
> happens when a command isn't found, right? Indeed I would expect error
> messages to be printed by the process that tried resolving the command,
> which I thought is usually not a subshell.
> 
> ~ # strace -fe trace=process bash -c 'foo'
> execve("/bin/bash", ["bash", "-c", "foo"], 0x7ffd42249af0 /* 61 vars */) 
> = 0
> arch_prctl(ARCH_SET_FS, 0x7f6bbde9fe00) = 0
> bash: foo: command not found
> exit_group(127) = ?
> +++ exited with 127 +++
> 
> Any redirections applied to the command ought to still apply to the
> handler with or without the subshell, and a handler can always save
> and restore FDs if it had to redirect output with exec. If the handler
> wants to guarantee output to the tty it pretty much has to use /dev/tty,
> again with or without the subshell.
> 
> Anyway I know this isn't new and there's probably some code out there
> that depends on the implicit subshell by now.
> 

Thinking out loud some more... it does make sense that a user in an
interactive session expects commands to not alter their shell environment,
and a badly written command_not_found_handle could do that, possibly
without the user's knowledge on systems that put a handler in a global
bashrc (likely the most common scenario).

On the other hand a user that actually defines their own handler could
have a million reasons to want to propagate some effect to the interactive
process, e.g. defining an alias or altering PS1. Same for non-interactive
scripts.



signature.asc
Description: OpenPGP digital signature


Re: command_not_found_handle documentation omission

2017-10-08 Thread Dan Douglas
On 10/08/2017 09:47 AM, Chet Ramey wrote:
> It was originally intended to take the place of the error message that
> bash prints when it can't find a program to execute. That message was
> printed by the subshell forked to execute the command, so the message could
> be redirected (nearly ll shells do it that way). If you're going to run a
> command, you run it in the same context as the error message.

Bash does PATH resolution prior to forking any subshell and no fork
happens when a command isn't found, right? Indeed I would expect error
messages to be printed by the process that tried resolving the command,
which I thought is usually not a subshell.

~ # strace -fe trace=process bash -c 'foo'
execve("/bin/bash", ["bash", "-c", "foo"], 0x7ffd42249af0 /* 61 vars */) = 0
arch_prctl(ARCH_SET_FS, 0x7f6bbde9fe00) = 0
bash: foo: command not found
exit_group(127) = ?
+++ exited with 127 +++

Any redirections applied to the command ought to still apply to the
handler with or without the subshell, and a handler can always save
and restore FDs if it had to redirect output with exec. If the handler
wants to guarantee output to the tty it pretty much has to use /dev/tty,
again with or without the subshell.

Anyway I know this isn't new and there's probably some code out there
that depends on the implicit subshell by now.



signature.asc
Description: OpenPGP digital signature


Re: command_not_found_handle documentation omission

2017-10-08 Thread Chet Ramey
On 10/8/17 4:54 AM, Dan Douglas wrote:
> On 10/07/2017 02:53 PM, Martijn Dekker wrote:
>> The bash manual and info pages state:
>>
>> | If the search is unsuccessful, the shell searches for a
>> | defined shell function named 'command_not_found_handle'.  If that
>> | function exists, it is invoked with the original command and the
>> | original command's arguments as its arguments, and the function's
>> | exit status becomes the exit status of the shell.
>>
>> This fails to mention that command_not_found_handle() is run in the
>> subshell forked to 'exec' the command, so even an explicit 'exit' will
>> not exit anything but that subshell. It also means a command handler
>> can't do anything that influences the main shell, except send it a
>> signal with 'kill'.
> 
> Yeah I wish it didn't do that. If I wanted a subshell I'd add one myself.

It was originally intended to take the place of the error message that
bash prints when it can't find a program to execute. That message was
printed by the subshell forked to execute the command, so the message could
be redirected (nearly ll shells do it that way). If you're going to run a
command, you run it in the same context as the error message.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/



signature.asc
Description: OpenPGP digital signature


Re: command_not_found_handle documentation omission

2017-10-08 Thread Dan Douglas
On 10/07/2017 02:53 PM, Martijn Dekker wrote:
> The bash manual and info pages state:
> 
> | If the search is unsuccessful, the shell searches for a
> | defined shell function named 'command_not_found_handle'.  If that
> | function exists, it is invoked with the original command and the
> | original command's arguments as its arguments, and the function's
> | exit status becomes the exit status of the shell.
> 
> This fails to mention that command_not_found_handle() is run in the
> subshell forked to 'exec' the command, so even an explicit 'exit' will
> not exit anything but that subshell. It also means a command handler
> can't do anything that influences the main shell, except send it a
> signal with 'kill'.

Yeah I wish it didn't do that. If I wanted a subshell I'd add one myself.



signature.asc
Description: OpenPGP digital signature