Skip to contentSkip to conversation

no match should be no string ?

DISCUSSION Marc Chantreux 2 participants 5 messages Nov 28, 2021

lore
Share & tools
lore
#0 lore raw

hello people,

I'm porting scripts from zsh to dash using version 0.5.11+git20200708+dd9ef66-5 from debian and
surprised to realize that the result of a glob failure is the glob itself (when i expected an empty string).

    for it in *.txt; do gzip $it; done
    ERR: gzip: *.g: No such file or directory

    note () >&2 echo "$@"
    rm -rf *.g
    set *.g
    case $#
        in (0) echo ok
        ;; (*) echo nope
    esac
    ERR: nope

not only unexpected but it also make it harder to deal with. i found nothing about that in the manual so before i dig into the code and provide a patch, i would like to know if this is an expected behavior with a rationale in it (like a bug to bug clone or POSIX compliance).

regards,

Signature · 4 lines
Marc Chantreux
Direction du numérique de l'Université de Strasbourg
Pôle de Calcul et Services Avancés à la Recherche (CESAR)
http://annuaire.unistra.fr/p/20200
#1 lore raw
Quoted 6 lines · Marc Chantreux

hello people,

I'm porting scripts from zsh to dash using version 0.5.11+git20200708+dd9ef66-5 from debian and
surprised to realize that the result of a glob failure is the glob itself (when i expected an empty string).

Hi, yes, this is expected, this is standard POSIX sh behaviour and implemented by all POSIX sh-compatible shells. It should even be what zsh does when running in POSIX mode, but I do not have it installed right now to check.

In bash, it is optional, you get the glob itself by default, but there is a "nullglob" shell option you can set to get what you are asking for.

In ksh, it is optional, you get the glob itself by default, but there is a special thing where you can start a glob with ~(N) to change only that glob only to expand to nothing if there is no match.

Both of those are valid extensions that don't affect POSIX conformance.

I personally suspect dash will not want to implement either extension until POSIX decides which extension, if either/any, to standardise at some point.

Cheers,
Harald van Dijk

#2 lore raw

hello,

Quoted 4 lines

Hi, yes, this is expected, this is standard POSIX sh behaviour and implemented by all POSIX sh-compatible shells. It should even be what zsh does when running in POSIX mode, but I do not have it installed right now to check.

You're right!

emulate sh
set *no_way_this_glob_matches*
echo $@

outputs *no_way_this_glob_matches*

Quoted 2 lines

In bash, it is optional, you get the glob itself by default, but there is a "nullglob" shell option you can set to get what you are asking for.

emulate zsh
set *no_way_this_glob_matches*
echo $@
ERR: zsh: no matches found: *no_way_this_glob_matches*

emulate zsh
set -- *no_way_this_glob_matches*(N)
echo $#
OUT: 0

Quoted 3 lines

In ksh, it is optional, you get the glob itself by default, but there is a special thing where you can start a glob with ~(N) to change only that glob only to expand to nothing if there is no match.

ok so (N) is a ksh inspired! thanks for the fish.

Quoted 2 lines

I personally suspect dash will not want to implement either extension until POSIX decides which extension, if either/any, to standardise at some point.

which is understandable but not usable because of

* the ambiguity when $# is 1: there is no way to know if i have no match or if a very bad person named its file \*no_way_this_glob_matches\*.
* i can't trust a loop like
for it in \*no_way_this_glob_matches\*; do gzip "$it"; done

fortunately, this POSIX problem will not affect my daily life as

* i use zsh when i want a QND script or need an interactive shell
* for anything else, i use find . -name \*no_way_this_glob_matches\* -maxdepth 1 -print0

thank you so much for your help.

Signature · 4 lines
Marc Chantreux
Direction du numérique de l'Université de Strasbourg
Pôle de Calcul et Services Avancés à la Recherche (CESAR)
http://annuaire.unistra.fr/p/20200
#3 lore raw
Quoted 2 lines · Marc Chantreux

* the ambiguity when $# is 1: there is no way to know if i have no match or if a very bad person named its file \*no_way_this_glob_matches\*.

Agreed that that is annoying.

If your pattern includes literal characters, there is a complicated workaround that you can apply directly in the pattern: use the pattern

*[n]o_way_this_glob_matches*

If you get back exactly '*[n]o_way_this_glob_matches*', that is because the glob did not match anything. A file by that name would not be picked up by the glob. If you get back anything else, it was found by the glob.

Otherwise, you would need to 'test -e' to double-check.

Cheers,
Harald van Dijk

#4 lore raw

hello Harald,

Quoted 3 lines

If you get back exactly '*[n]o_way_this_glob_matches*', that is because the glob did not match anything. A file by that name would not be picked up by the glob. If you get back anything else, it was found by the glob.

correct but still: this behavior isn't "intellectually correct" to me so i'll bet on find|xargs (which is great for many other reasons anyway).

thanks for trying so hard :)

regards

Signature · 4 lines
Marc Chantreux
Direction du numérique de l'Université de Strasbourg
Pôle de Calcul et Services Avancés à la Recherche (CESAR)
http://annuaire.unistra.fr/p/20200