no match should be no string ?
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: nopenot 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
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
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
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
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