Subject: bug#33942: ls directly uses filename as option parameter

From: Assaf Gordon <[email-masked]>
Date: Wed, 2 Jan 2019 02:21:22 -0700

tags 33942 notabug
close 33942
stop

Hello,

On 2018-12-31 7:52 p.m., westlake wrote:
>   I have known long time about certain commands that use "--" as a 
> specially reserved parameter. However, I find the behaviour of it with 
> ls showing a little confusing results and believe this surmounts to a bug,

What you describe below is not a bug, but the indented behavior.

>[...] and found out that 
> having a file called "./--" creates unpredictable behaviour [...]

First,
It's important to understand the filename is not "./--" (4 characters),
but "--" (2 characters) in the current directory ("./").

This is similar to typing "/home/user/--".
You wouldn't say the filename is "/home/user/--" - the filename is "--"
and it is in the directory "/home/user/".

While it might sound like splitting hairs, this is critical to
understand what's going on here. The filename starts with (and contains
only) two minus characters.

> $ touch 0 ./--a ./-a ./-_a ./--
> 
> $ ls -lad  -* [^-]*

Second,
It is important to understand that it is the shell which does
the filename completion (e.g. "*" and "-*" etc.).
The filename expiation happens before "ls" is even executed.

With this in mind, it'll be easier to understand what's
going on if you add "echo" to every command, and look
at what's printed:

   $ echo ls -lad  -* [^-]*
   ls -lad -- -a -_a --a 0

   $ echo ls -lad --  -* [^-]*
   ls -lad -- -- -a -_a --a 0

   $ echo ls -lad -- *
   ls -lad -- -- 0 -a -_a --a

> Notice that example 2, "-*" is being parsed with "--a" ,   is "./--" not 
> showing up due to "design" or is this a "bug" ?  If "--a" is getting 
> listed, then so should the file called "./--",

Not a bug.

Using "echo", you can see what are the exact parameters that are passed
to "ls".

And then follow these simple steps:
1. The first "--" tells ls to stop processing options.
2. anything that starts with a dash BEFORE the first "--" marker
is taken to be an option.
3. anything  AFTER the first "--" marker is taken to be a file name 
(strings starting with a single dash, and including additional "--" 
strings).

That's it - and it works consistently for most GNU programs, not just ls.

> Okay I understand ls complaining:
> "
> ls -lad *
> ls: invalid option -- '_'
> Try 'ls --help' for more information.

using "echo" will show what's happening:

   $ rm ./--
   $ echo ls -lad *
   ls -lad 0 -a -_a --a

With the file "--" gone (which was seen be "ls" as the "--" marker),
ls now sees "-a" as an option (a valid option),
then it sees "-_a" (and "_" is not a valid option) - hence the error 
message.

> ^ but it is counter-intuitive because having a file called "./--", and 
> this command passes.
> 

If you follow the simple steps above (and use "echo" to see how the
shell performs filename expansion), I hope all the other issues you've
listed in your email will become clear.

If not - please do write with specific cases.

I'm closing this as "not a bug", but discussion can continue
by replying to this thread.

-assaf