Bug 1767 - Inconsistend wildcard expansion in 'ls *'
Summary: Inconsistend wildcard expansion in 'ls *'
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: sftp (show other bugs)
Version: 5.5p1
Hardware: All All
: P2 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-05 23:13 AEST by Grigory
Modified: 2010-06-19 02:16 AEST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Grigory 2010-05-05 23:13:03 AEST
They way wilcard expansion is done in 'ls *' depends on the number of files in the current directory.
If there are two or more files/subdirs in the current directory, 'ls *' produces the list of current directory (this is ok).
But if there is only one subdirectory in the current directory, 'ls *' also  produces the list of files in this subdirectory.
This is inconsistent approach to my mind.

Steps to reproduce:

$ touch file1 file2
$ sftp user@host
Connected to host.
Changing to: /home/user/
sftp> mkdir test
sftp> cd test 
sftp> mkdir dir1
sftp> mkdir dir2
sftp> put file* dir1
Uploading file1 to /home/user/test/dir1/file1
Uploading file2 to /home/user/test/dir1/file2
sftp> ls -1 *
dir1/
dir2/

Note the result of the above command. Assume this is a correct behaviour. Now we'll remove dir2 and see how 'ls -1 *' output changes.
I expect to see only 'dir1/' in the output.

sftp> rmdir dir2
sftp> ls -1 *
dir1/file1
dir1/file2
sftp> 

We can see that the output is quite different from our expectations.
It showed 'dir1/file1  dir1/file2' instead of 'dir1/'.

This bug appeared in somewhere around OpenSSH_4.2p1, maybe a little bit earlier. It is still present in OpenSSH_5.5p1-snap20100505.

This bug does NOT present in OpenSSH_3.8.1p1.
Comment 1 Damien Miller 2010-06-18 14:53:16 AEST
This is the special case code:

   755  /*
   756   * If the glob returns a single match and it is a directory,
   757   * then just list its contents.
   758   */
   759   if (g.gl_matchc == 1) {
   760       if ((a = do_lstat(conn, g.gl_pathv[0], 1)) == NULL) {
   761           globfree(&g);
   762           return (-1);
   763       }
   764       if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
   765           S_ISDIR(a->perm)) {
   766                int err;
   767  
   768                err = do_ls_dir(conn, g.gl_pathv[0], strip_path,
 lflag);
   769                globfree(&g);
   770                return (err);
   771       }
   772   }

Arguably, the special case behaviour is more consistent with a normal shell when executing "ls *"
Comment 2 Grigory 2010-06-19 02:16:17 AEST
This behaviour is confusing for scripts that invoke sftp in batch mode.
"ls -1 *" is a convenient way for a script to differ directories from files because directories are marked by '/' in the end of them.