Weirdness with rpm and * wildcard

Hi,

I just discovered something very weird. It looks like when I use rpm with the * wildcard, it will work with some packages, but not all.

Take the following example.

# rpm -qa | grep pidgin 
**pidgin**-plugin-otr-lang-4.0.2-lp152.3.6.noarch 
**pidgin**-plugin-otr-4.0.2-lp152.3.6.x86_64 
**pidgin**-2.13.0-lp152.6.4.x86_64

Here’s a different way to do this:

[FONT=monospace]# rpm -qa pidgin* 
pidgin-plugin-otr-lang-4.0.2-lp152.3.6.noarch 
pidgin-plugin-otr-4.0.2-lp152.3.6.x86_64 
pidgin-2.13.0-lp152.6.4.x86_64
[/FONT]

Now let’s try the same thing with “python” instead of “pidgin”:

# rpm -qa | grep python 
**python**3-pycups-1.9.74-lp152.1.2.x86_64 
**python**3-cffi-1.13.2-lp152.1.4.x86_64 
**python**2-gobject-3.34.0-lp152.2.3.x86_64 
**python**3-urllib3-1.24-lp152.5.3.1.noarch
...

And here comes the weird thing:

# rpm -qa python*

And that’s it. Nothing. No result.

The expected behavior here is to list all packages whose names begin with the “python” character string. But I get nothing.

I tried this on my sandbox PC as well as on my workstation, with the same result.

Anybody can offer an explanation for this mysterious behavior?

Cheers,

Niki

I assume that wild card * is to be interpreted by the rpm command.
Then better hide it from interpreting by the shell (bash) by quoting:

rpm -qa 'python*'

Its working here:

# rpm -qa python*
python2-pycurl-7.43.0.2-lp152.2.9.x86_64
python3-pycparser-2.17-lp152.3.4.noarch
python3-termcolor-1.1.0-lp152.4.1.noarch
python2-Werkzeug-0.14.1-lp152.3.4.noarch
python2-certifi-2018.1.18-lp152.3.3.noarch
python3-createrepo_c-0.15.4-lp152.2.5.x86_64
python3-requests-toolbelt-0.9.1-lp152.1.1.noarch
python3-mpi4py-3.0.3-lp152.1.16.x86_64
python3-watchdog-0.10.2-lp152.3.1.noarch
python3-numba-0.37.0-lp152.4.9.x86_64
python3-cachetools-2.0.1-lp152.3.3.noarch
python2-pytz-2019.1-lp152.3.3.1.noarch
python2-olefile-0.44-lp152.3.3.noarch
python2-decorator-4.2.1-lp152.3.3.noarch
python2-pip-10.0.1-lp152.4.6.1.noarch

Of course is that possible. It depends on the result of the “file expansion” done by bash.
In most cases there is no file that fits pidgin* and thus the result of the bash expansion is pigin* and that is fed as an argument to the rpm command. It a case of pure luck, but not a case of knowing how the shell works.

In the case that python* really expands into one or more file names, simply because they are in the working directory, those name(s) wil be fed as argument(s) to the rpm command. Most probably resulting in package names that do not exist.

We see this often happening the same with the zypper command. That also is able to use * as a wild character in certain cases. Those who wrote the zypper man page are very nice to their readers by mentioning several times in that page things like

Note

If you use blanks around the operator you need to quote the string or escape the blanks according to the rules of the shell you are using.

Examples:

$ zypper se ‘yast*’

Search for YaST packages (quote the string to prevent the shell from expanding the wildcard).

But most people simply start typing in the shell without thinking about the fact that they are typing in the shell.

It is the old saying:
Unix/Linux will do what you tell it to do, not what you think you tell it to do.

Illustration.

I have a program (script) that shows all arguments it is given when called. This then gives an illustration on what another command like rpm is given.

henk@boven:~/test/cedir> cat ~/bin/ce
#/usr/bin/bash

echo $*

The working directory is ~/test/cedir and it has the following files:

henk@boven:~/test/cedir> ls -l
total 0
-rw-r--r-- 1 henk wij 0 May 16 21:49 aap
-rw-r--r-- 1 henk wij 0 May 16 21:49 aap1
-rw-r--r-- 1 henk wij 0 May 16 21:49 noot

Now a ce command is given to the shell and the shell will do a lot with that line, but at the end it will start ce with some arguments and ce will print what it gets.

henk@boven:~/test/cedir> ce *
aap aap1 noot
henk@boven:~/test/cedir> ce aap*
aap aap1
henk@boven:~/test/cedir> ce noot*
noot
henk@boven:~/test/cedir> ce mies*
mies*
henk@boven:~/test/cedir> 

I hope this is clear. Only in the last case when the expansion leads to nothing the * character will get through to the ce command.

Thanks ! That did the trick !

Fine you have it working. But it is NOT a trick. And what you experienced is not “mysterious behavior”.

Just a note.

If I try:

rpm -qa pidgin*

I get an error message “rpm: No match.”. That’s because I use “csh” as my shell. And “csh” complains if a wildcard does not match anything, while “bash” just passes on the wildcard in that case.

I’m not suggesting that you change shells. But this does illustrate that your question was entirely about the shell rather than about the “rpm” command.

That is why I stressed “bash” a few times instead of only saying “shell”. It matters what you are using as intermediate between you and the kernel. I can not help it, but those “using the CLI” should know, or at least know where to find, the documentation (man page) of the shell they are using. Using Unix/Linux has a steep learning curve.

And not only was the question about bash instead of rpm, there was also no “weirdness” :wink:

Learning curve is user dependent. Any shell preprocesses the command line in its own way. bash does: https://www.oreilly.com/library/view/learning-the-bash/1565923472/ch07s03.html When done the command is run: How do I parse command line arguments in Bash? - Stack Overflow

Don’t try to figure out yourself. Copying from the web is faster in most cases: add google_api_key to your google maps templates (they made the key mandatory in 2017)

find /home/Albums/NeueBilder/ -name Karte.htt -exec sed -i -e 's/google_api_key\ =\ '\'''\''/google_api_key\ =\ '\''A...........'\''/g' {} \;