[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: reportbug: don't know: bug in apt [list] or in grep



On Thu, Jan 19, 2023 at 12:11:43PM +0100, Christoph Brinkhaus wrote:
> For curiosity If have done a small test as below.
> Unfortunately there are a few outputs in German. For this comparisons
> the exact meanings of the German text has no importance at all.
> 
> 1. The first command of the original poster:
> chris@lenovo ~> apt list sudo*
> fish: No matches for wildcard 'sudo*'. See `help expand`.
> apt list sudo*
>          ^
> 2. Create an empty file to see the effect:
> chris@lenovo ~> touch sudo
> 
> 3. The first command of the original poster:
> chris@lenovo ~> apt list sudo*
> Auflistung… Fertig
> sudo/stable-security,now 1.9.5p2-3+deb11u1 amd64  [Installiert,automatisch]
> N: Es gibt 1 zusätzliche Version. Bitte verwenden Sie die Option »-a«, um sie anzuzeigen.

Your examples are excellent, but there's one more piece to this story.
The behavior of a glob that doesn't match any files (e.g. your 1.)
depends on the shell, and on the settings that are chosen within that
shell.

In bash, with default settings, a glob that doesn't match any files
is passed on literally as a command argument.  The classic example
of this is demonstrated by "ls":

unicorn:~$ ls *.ttx
ls: cannot access '*.ttx': No such file or directory

If I misspell "*.txt" as "*.ttx" I get this message.  Bash (my shell)
saw the *.ttx glob, and tried to expand it to the list of matching
filenames in my directory.  There aren't any, so it passed the glob
along without expanding it.  This allowed ls to see the original glob
just as I had typed it, and to include it in its error message.

If I did the same thing with apt list sudo* I would get this:

unicorn:~$ ls sudo*
ls: cannot access 'sudo*': No such file or directory
unicorn:~$ apt list sudo*
Listing... Done
sudo-ldap/stable-security 1.9.5p2-3+deb11u1 amd64
sudo-ldap/stable-security 1.9.5p2-3+deb11u1 i386
sudo/stable-security,now 1.9.5p2-3+deb11u1 amd64 [installed]
sudo/stable-security 1.9.5p2-3+deb11u1 i386
sudoku-solver/stable 1.0.1-2 amd64
sudoku-solver/stable 1.0.1-2 i386
sudoku/stable 1.0.5-2+b3 amd64
sudoku/stable 1.0.5-2+b3 i386

Since there are no files matching the sudo* glob in my directory, bash
passes it along untouched, and apt uses it as a matching pattern against
package names.

The fact that this *appears* to work is what causes so much confusion.
It will "work" some of the time, but not all of the time, and you'll
get different results depending on which directory you're in, on which
computer.

Bash has two other settings for handling unmatched globs.  The first one
is called "nullglob", and if it's turned on, an unmatched glob is simply
discarded from the command argument list.

unicorn:~$ bash
unicorn:~$ shopt | grep glob
dotglob        	off
extglob        	off
failglob       	off
globasciiranges	on
globstar       	off
nocaseglob     	off
nullglob       	off
unicorn:~$ shopt -s nullglob
unicorn:~$ apt list sudo* | head

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Listing...
0ad-data-common/stable,stable 0.0.23.1-1.1 all
0ad-data/stable,stable 0.0.23.1-1.1 all
0ad/stable 0.0.23.1-5+b1 amd64
0ad/stable 0.0.23.1-5+b1 i386
0install-core/stable 2.16-1 amd64
0install-core/stable 2.16-1 i386
0install/stable 2.16-1 amd64
0install/stable 2.16-1 i386
0xffff/stable 0.9-1 amd64

In this case, the unmatched sudo* glob is dropped altogether, and the
resulting command is simply "apt list".  I knew what would happen, so I
piped it to head, to shorten the output.

The other setting is called "failglob", and if it's turned on, an
unmatched glob causes an error at the shell level, and prevents execution
of the command.

unicorn:~$ shopt -u nullglob; shopt -s failglob
unicorn:~$ apt list sudo*
bash: no match: sudo*
unicorn:~$ exit
exit

This is very much like what your fish example did, and what (t)csh does
by default, if I remember correctly.

So, just to add to the list of people who've already said it: always
quote the patterns that you pass to apt list, because you want apt
to use them directly, without your shell interfering.


Reply to: