* Equivalent of set -- *(DN) in sh @ 2015-01-18 18:28 Nikolai Weibull 2015-01-18 19:07 ` Roman Neuhauser ` (2 more replies) 0 siblings, 3 replies; 15+ messages in thread From: Nikolai Weibull @ 2015-01-18 18:28 UTC (permalink / raw) To: Zsh Users Hi! Is there any way to get the equivalent of Zsh’s set -- *(DN) in sh? Most important here would be NULL_GLOB, as, by default, sh simply leaves the * if there are no files to match. Thanks! ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-18 18:28 Equivalent of set -- *(DN) in sh Nikolai Weibull @ 2015-01-18 19:07 ` Roman Neuhauser 2015-01-18 19:43 ` Nikolai Weibull 2015-01-18 19:31 ` ZyX 2015-01-18 20:46 ` Eric Cook 2 siblings, 1 reply; 15+ messages in thread From: Roman Neuhauser @ 2015-01-18 19:07 UTC (permalink / raw) To: Nikolai Weibull; +Cc: Zsh Users # now@disu.se / 2015-01-18 19:28:42 +0100: > Is there any way to get the equivalent of Zsh´s > > set -- *(DN) > > in sh? Most important here would be NULL_GLOB, as, by default, sh > simply leaves the * if there are no files to match. set -- $(find .* * -maxdepth 0 -type d) does not handle names with spaces. -- roman ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-18 19:07 ` Roman Neuhauser @ 2015-01-18 19:43 ` Nikolai Weibull 2015-01-18 20:32 ` Roman Neuhauser 0 siblings, 1 reply; 15+ messages in thread From: Nikolai Weibull @ 2015-01-18 19:43 UTC (permalink / raw) To: Roman Neuhauser; +Cc: Zsh Users On Sun, Jan 18, 2015 at 8:07 PM, Roman Neuhauser <neuhauser@sigpipe.cz> wrote: > # now@disu.se / 2015-01-18 19:28:42 +0100: >> Is there any way to get the equivalent of Zsh´s >> >> set -- *(DN) >> >> in sh? Most important here would be NULL_GLOB, as, by default, sh >> simply leaves the * if there are no files to match. > > set -- $(find .* * -maxdepth 0 -type d) > > does not handle names with spaces. Which is unsatisfactory, as $() isn’t in all versions of sh, -maxdepth is GNU specific, and .* and * will be expanded by the shell, not by find, so we’ve gained nothing and lost quite a bit. Oh, and who said anything about only including directories? ;-) ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-18 19:43 ` Nikolai Weibull @ 2015-01-18 20:32 ` Roman Neuhauser 0 siblings, 0 replies; 15+ messages in thread From: Roman Neuhauser @ 2015-01-18 20:32 UTC (permalink / raw) To: Nikolai Weibull; +Cc: Zsh Users # now@disu.se / 2015-01-18 20:43:55 +0100: > On Sun, Jan 18, 2015 at 8:07 PM, Roman Neuhauser <neuhauser@sigpipe.cz> wrote: > > # now@disu.se / 2015-01-18 19:28:42 +0100: > >> Is there any way to get the equivalent of Zsh´s > >> > >> set -- *(DN) > >> > >> in sh? Most important here would be NULL_GLOB, as, by default, sh > >> simply leaves the * if there are no files to match. > > > > set -- $(find .* * -maxdepth 0 -type d) > > > > does not handle names with spaces. > > Which is unsatisfactory, as $() isn´t in all versions of sh, then use `find ...`, problem solved. btw if your requirements are this stringent you would have done well if you laid them out upfront. > -maxdepth is GNU specific it's not, at least all BSDs have it as well. again, what operating systems do you need to support? > and .* and * will be expanded by the shell, not by find you can `find . -maxdepth 1 -mindepth 1`, but the paths will be prefixed with "./". you could of ocurse append `| sed 's:..::'`. OTOH, what's the problem with the shell expanding the globs? if .* or * does not exist, sh leaves that there as-is, find cannot chdir into it, and definitely won't print it. > Oh, and who said anything about only including directories? ;-) yeah, that was a brainfart, sorry. -- roman ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-18 18:28 Equivalent of set -- *(DN) in sh Nikolai Weibull 2015-01-18 19:07 ` Roman Neuhauser @ 2015-01-18 19:31 ` ZyX 2015-01-18 19:46 ` Nikolai Weibull 2015-01-18 20:46 ` Eric Cook 2 siblings, 1 reply; 15+ messages in thread From: ZyX @ 2015-01-18 19:31 UTC (permalink / raw) To: Nikolai Weibull, Zsh Users 18.01.2015, 21:36, "Nikolai Weibull" <now@disu.se>: > Hi! > > Is there any way to get the equivalent of Zsh’s > > set -- *(DN) > > in sh? Most important here would be NULL_GLOB, as, by default, sh > simply leaves the * if there are no files to match. > > Thanks! If you are OK with bash then you may use `shopt -s nullglob; shopt -s dotglob` and use `set -- *`. Note that solution posted by Roman Neuhauser does handle names with spaces and tabs, but not newlines, if you set $IFS to a newline. As-is it has problems with all characters in IFS which are not just space, but also tab and newline. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-18 19:31 ` ZyX @ 2015-01-18 19:46 ` Nikolai Weibull 0 siblings, 0 replies; 15+ messages in thread From: Nikolai Weibull @ 2015-01-18 19:46 UTC (permalink / raw) To: ZyX; +Cc: Zsh Users On Sun, Jan 18, 2015 at 8:31 PM, ZyX <kp-pav@yandex.ru> wrote: > 18.01.2015, 21:36, "Nikolai Weibull" <now@disu.se>: >> Is there any way to get the equivalent of Zsh’s >> >> set -- *(DN) >> >> in sh? Most important here would be NULL_GLOB, as, by default, sh >> simply leaves the * if there are no files to match. > If you are OK with bash then you may use `shopt -s nullglob; shopt -s dotglob` and use `set -- *`. I’m not. Depending on Bash is like depending on Zsh these days, I’d say, in terms of availability. > Note that solution posted by Roman Neuhauser does handle names with spaces and tabs, but not newlines, if you set $IFS to a newline. As-is it has problems with all characters in IFS which are not just space, but also tab and newline. The solution has to be functionally equivalent. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-18 18:28 Equivalent of set -- *(DN) in sh Nikolai Weibull 2015-01-18 19:07 ` Roman Neuhauser 2015-01-18 19:31 ` ZyX @ 2015-01-18 20:46 ` Eric Cook 2015-01-19 15:51 ` ZyX 2 siblings, 1 reply; 15+ messages in thread From: Eric Cook @ 2015-01-18 20:46 UTC (permalink / raw) To: zsh-users On 01/18/2015 01:28 PM, Nikolai Weibull wrote: > Hi! > > Is there any way to get the equivalent of Zsh’s > > set -- *(DN) > > in sh? Most important here would be NULL_GLOB, as, by default, sh > simply leaves the * if there are no files to match. > > Thanks! match() { test "$#" -gt 2 && return test -e "$1" && return return 1 } set -- for pat in '.[^.]*' '*'; do # *(DN) ignores . and .. if match $pat; then set -- "$@" $pat fi done unset pat test "$#" -gt 0 && printf '%s\n' "$@" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-18 20:46 ` Eric Cook @ 2015-01-19 15:51 ` ZyX 2015-01-19 15:55 ` ZyX ` (2 more replies) 0 siblings, 3 replies; 15+ messages in thread From: ZyX @ 2015-01-19 15:51 UTC (permalink / raw) To: Eric Cook, zsh-users 18.01.2015, 23:53, "Eric Cook" <llua@gmx.com>: > On 01/18/2015 01:28 PM, Nikolai Weibull wrote: >> Hi! >> >> Is there any way to get the equivalent of Zsh’s >> >> set -- *(DN) >> >> in sh? Most important here would be NULL_GLOB, as, by default, sh >> simply leaves the * if there are no files to match. >> >> Thanks! > > match() { > test "$#" -gt 2 && return > test -e "$1" && return > return 1 > } > > set -- > for pat in '.[^.]*' '*'; do # *(DN) ignores . and .. `..foo` is a valid name, but it is being excluded. You need to add `'.??*'` to the list of patterns. > if match $pat; then > set -- "$@" $pat > fi > done > unset pat > > test "$#" -gt 0 && printf '%s\n' "$@" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-19 15:51 ` ZyX @ 2015-01-19 15:55 ` ZyX 2015-01-19 16:02 ` ZyX 2015-01-19 21:44 ` Eric Cook [not found] ` <54BD7ABB.5070501__36205.2317861982$1421704010$gmane$org@gmx.com> 2 siblings, 1 reply; 15+ messages in thread From: ZyX @ 2015-01-19 15:55 UTC (permalink / raw) To: Eric Cook, zsh-users 19.01.2015, 18:51, "ZyX" <kp-pav@yandex.ru>: > 18.01.2015, 23:53, "Eric Cook" <llua@gmx.com>: >> On 01/18/2015 01:28 PM, Nikolai Weibull wrote: >>> Hi! >>> >>> Is there any way to get the equivalent of Zsh’s >>> >>> set -- *(DN) >>> >>> in sh? Most important here would be NULL_GLOB, as, by default, sh >>> simply leaves the * if there are no files to match. >>> >>> Thanks! >> match() { >> test "$#" -gt 2 && return >> test -e "$1" && return >> return 1 >> } >> >> set -- >> for pat in '.[^.]*' '*'; do # *(DN) ignores . and .. > > `..foo` is a valid name, but it is being excluded. You need to add `'.??*'` to the list of patterns. No, this may make duplicates. Then `'..?*'`. >> if match $pat; then >> set -- "$@" $pat >> fi >> done >> unset pat >> >> test "$#" -gt 0 && printf '%s\n' "$@" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-19 15:55 ` ZyX @ 2015-01-19 16:02 ` ZyX 2015-01-19 16:16 ` ZyX 0 siblings, 1 reply; 15+ messages in thread From: ZyX @ 2015-01-19 16:02 UTC (permalink / raw) To: Eric Cook, zsh-users 19.01.2015, 18:55, "ZyX" <kp-pav@yandex.ru>: > 19.01.2015, 18:51, "ZyX" <kp-pav@yandex.ru>: >> 18.01.2015, 23:53, "Eric Cook" <llua@gmx.com>: >>> On 01/18/2015 01:28 PM, Nikolai Weibull wrote: >>>> Hi! >>>> >>>> Is there any way to get the equivalent of Zsh’s >>>> >>>> set -- *(DN) >>>> >>>> in sh? Most important here would be NULL_GLOB, as, by default, sh >>>> simply leaves the * if there are no files to match. >>>> >>>> Thanks! >>> match() { >>> test "$#" -gt 2 && return >>> test -e "$1" && return >>> return 1 >>> } >>> >>> set -- >>> for pat in '.[^.]*' '*'; do # *(DN) ignores . and .. >> `..foo` is a valid name, but it is being excluded. You need to add `'.??*'` to the list of patterns. > > No, this may make duplicates. Then `'..?*'`. And you must replace `[^.]` with `[!.]`. mksh does not support `[^]` and treats this as `[\^.]`, but other shells I have (dash, ksh, zsh (in sh emulation mode), bash, busybox ash) are fine with both `[!.]` and `[^.]`. >>> if match $pat; then >>> set -- "$@" $pat >>> fi >>> done >>> unset pat >>> >>> test "$#" -gt 0 && printf '%s\n' "$@" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-19 16:02 ` ZyX @ 2015-01-19 16:16 ` ZyX 0 siblings, 0 replies; 15+ messages in thread From: ZyX @ 2015-01-19 16:16 UTC (permalink / raw) To: Eric Cook, zsh-users 19.01.2015, 19:02, "ZyX" <kp-pav@yandex.ru>: > 19.01.2015, 18:55, "ZyX" <kp-pav@yandex.ru>: >> 19.01.2015, 18:51, "ZyX" <kp-pav@yandex.ru>: >>> 18.01.2015, 23:53, "Eric Cook" <llua@gmx.com>: >>>> On 01/18/2015 01:28 PM, Nikolai Weibull wrote: >>>>> Hi! >>>>> >>>>> Is there any way to get the equivalent of Zsh’s >>>>> >>>>> set -- *(DN) >>>>> >>>>> in sh? Most important here would be NULL_GLOB, as, by default, sh >>>>> simply leaves the * if there are no files to match. >>>>> >>>>> Thanks! >>>> match() { >>>> test "$#" -gt 2 && return >>>> test -e "$1" && return >>>> return 1 >>>> } >>>> >>>> set -- >>>> for pat in '.[^.]*' '*'; do # *(DN) ignores . and .. >>> `..foo` is a valid name, but it is being excluded. You need to add `'.??*'` to the list of patterns. >> No, this may make duplicates. Then `'..?*'`. > > And you must replace `[^.]` with `[!.]`. mksh does not support `[^]` and treats this as `[\^.]`, but other shells I have (dash, ksh, zsh (in sh emulation mode), bash, busybox ash) are fine with both `[!.]` and `[^.]`. >>>> if match $pat; then >>>> set -- "$@" $pat >>>> fi >>>> done >>>> unset pat >>>> >>>> test "$#" -gt 0 && printf '%s\n' "$@" Also note that if you need *full* equivalent of *(DN) you need to do something with ordering. I have checked all the shells with for sh in dash ksh mksh zsh bash bb ; do $sh set--sDN.sh > set--sDN.$sh.log ; done with emulate -L sh &>/dev/null match() { test "$#" -gt 2 && return test -e "$1" && return return 1 } set -- for pat in '.[!.]*' '..?*' '*'; do # *(DN) ignores . and .. if match $pat; then set -- "$@" $pat fi done unset pat test "$#" -gt 0 && printf '>>%s<<\n' "$@" in set--sDN.sh file and have the following md5sums: % md5sum set--sDN.*.log | sort 4601e6d9c845fe88e5166db3be04cc75 set--sDN.bash.log 4601e6d9c845fe88e5166db3be04cc75 set--sDN.ksh.log 4601e6d9c845fe88e5166db3be04cc75 set--sDN.zsh.log ac2c245cdac664121a348c6b05ea2f44 set--sDN.bb.log ac2c245cdac664121a348c6b05ea2f44 set--sDN.dash.log ac2c245cdac664121a348c6b05ea2f44 set--sDN.mksh.log : two variants of ordering: bash/ksh/zsh: >>.abc<< >>.b<< >>.^foo<< >>..foo<< >> << >>1<< >>17<< >>2<< >>append-remove.bash<< >>getnumbers.bash<< >>grepdir<< >>nroff<< >>parinput.bash<< >>qwerty<< >>rl.sh<< >>script_path.bash<< >>set--sDN.bash.log<< >>set--sDN.bb.log<< >>set--sDN.dash.log<< >>set--sDN.ksh.log<< >>set--sDN.mksh.log<< >>set--sDN.sh<< >>set--sDN.zsh.log<< >>tes.bash<< >>test<< >>test2.bash<< >>test3.bash<< >>test.bash<< >>testdir<< >>test-rename.sh<< >>test-so-2914220.bash<< >>t.tar<< >>ttttt.tar.bz2<< >>ttttt.tar.gz<< bb/dash/mksh: >>.^foo<< >>.abc<< >>.b<< >>..foo<< >> << >>1<< >>17<< >>2<< >>append-remove.bash<< >>getnumbers.bash<< >>grepdir<< >>nroff<< >>parinput.bash<< >>qwerty<< >>rl.sh<< >>script_path.bash<< >>set--sDN.bash.log<< >>set--sDN.bb.log<< >>set--sDN.dash.log<< >>set--sDN.ksh.log<< >>set--sDN.mksh.log<< >>set--sDN.sh<< >>set--sDN.zsh.log<< >>t.tar<< >>tes.bash<< >>test<< >>test-rename.sh<< >>test-so-2914220.bash<< >>test.bash<< >>test2.bash<< >>test3.bash<< >>testdir<< >>ttttt.tar.bz2<< >>ttttt.tar.gz<< (note position of t.tar). I have verified that all tests emit essentially the same result by using `for f in set--sDN.*.log ; do cat $f | sort | md5sum ; done | uniq`. But both orderings are different from the zsh one: % zsh -f -c 'for f in *(DN); do echo ">>$f<<" ; done' >> << >>1<< >>17<< >>2<< >>.abc<< >>append-remove.bash<< >>.b<< >>.^foo<< >>..foo<< >>getnumbers.bash<< >>grepdir<< >>nroff<< >>parinput.bash<< >>qwerty<< >>rl.sh<< >>script_path.bash<< >>set--sDN.bash.log<< >>set--sDN.bb.log<< >>set--sDN.dash.log<< >>set--sDN.ksh.log<< >>set--sDN.mksh.log<< >>set--sDN.sh<< >>set--sDN.zsh.log<< >>tes.bash<< >>test<< >>test2.bash<< >>test3.bash<< >>test.bash<< >>testdir<< >>test-rename.sh<< >>test-so-2914220.bash<< >>t.tar<< >>ttttt.tar.bz2<< >>ttttt.tar.gz<< (note: I have filename with newline, this is why I added `>><<`.) ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-19 15:51 ` ZyX 2015-01-19 15:55 ` ZyX @ 2015-01-19 21:44 ` Eric Cook [not found] ` <54BD7ABB.5070501__36205.2317861982$1421704010$gmane$org@gmx.com> 2 siblings, 0 replies; 15+ messages in thread From: Eric Cook @ 2015-01-19 21:44 UTC (permalink / raw) To: zsh-users [-- Attachment #1: Type: text/plain, Size: 2490 bytes --] On 01/19/2015 10:51 AM, ZyX wrote: > `..foo` is a valid name, but it is being excluded. You need to add `'.??*'` to the list of patterns. Nice catch. On 01/19/2015 11:02 AM, ZyX wrote: > > And you must replace `[^.]` with `[!.]`. mksh does not support `[^]` and treats this as `[\^.]`, but other shells I have (dash, ksh, zsh (in sh emulation mode), bash, busybox ash) are fine with both `[!.]` and `[^.]`. and again. On 01/19/2015 11:16 AM, ZyX wrote: > emulate -L sh &>/dev/null While this is just an test, it should be pointed out that `&>' is also not defined nor does the same thing in all of the shells you tried. The correct way being `>/dev/null 2>&1'. On 01/19/2015 11:16 AM, ZyX wrote: > Also note that if you need *full* equivalent of *(DN) you need to do something with ordering. That depends on the user's locale, my LC_COLLATE was set to POSIX during my tests and each shell sorted the files the same. Setting LC_COLLATE to en_US.UTF-8 does give me the behavior you mentioned. I don't think there is a correct way to account for that. With: #!/bin/sh ${ZSH_VERSION+false} : || emulate sh match() { test "$#" -gt 2 && return test -e "$1" && return return 1 } set -- for pat in '..?*' '.[!.]*' '*'; do # I moved your added pattern to where POSIX locale would sort them. if match $pat; then set -- "$@" $pat fi done unset pat test "$#" -gt 0 && printf '%s ' "$@" % LC_COLLATE=POSIX % printf '%s ' *(DN) > ../zshdn--set.log % for sh in dash ksh mksh zsh bash bb; do $sh ../foo >../$sh--set.log; done % md5sum ../*--set.log 99970f198535e5fe62aeec1a13ebc639 ../bash--set.log 99970f198535e5fe62aeec1a13ebc639 ../bb--set.log 99970f198535e5fe62aeec1a13ebc639 ../dash--set.log 99970f198535e5fe62aeec1a13ebc639 ../ksh--set.log 99970f198535e5fe62aeec1a13ebc639 ../mksh--set.log 99970f198535e5fe62aeec1a13ebc639 ../zsh--set.log 99970f198535e5fe62aeec1a13ebc639 ../zshdn--set.log % LC_COLLATE=en_US.UTF-8 % printf '%s ' *(DN) > ../zshdn--set.log % for sh in dash ksh mksh zsh bash bb; do $sh ../foo >../$sh--set.log; done % md5sum ../*--set.log 28583c502cf605e105f794a37e1648da ../bash--set.log 28583c502cf605e105f794a37e1648da ../bb--set.log 99970f198535e5fe62aeec1a13ebc639 ../dash--set.log 28583c502cf605e105f794a37e1648da ../ksh--set.log 99970f198535e5fe62aeec1a13ebc639 ../mksh--set.log 4008c14ae7f0b2195c96d330d604ae50 ../zshdn--set.log 28583c502cf605e105f794a37e1648da ../zsh--set.log Strangely, the two zsh tests i did aren't the same. ^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <54BD7ABB.5070501__36205.2317861982$1421704010$gmane$org@gmx.com>]
* Re: Equivalent of set -- *(DN) in sh [not found] ` <54BD7ABB.5070501__36205.2317861982$1421704010$gmane$org@gmx.com> @ 2015-01-19 23:05 ` Stephane Chazelas 2015-01-22 7:44 ` Nikolai Weibull [not found] ` <CADdV=MsvuSAQMJVsr17Y7g2Nfjy95CQ007opQqv-7=RHjgjaKw__35342.9068615243$1421913204$gmane$org@mail.gmail.com> 0 siblings, 2 replies; 15+ messages in thread From: Stephane Chazelas @ 2015-01-19 23:05 UTC (permalink / raw) To: Eric Cook; +Cc: zsh-users 2015-01-19 16:44:27 -0500, Eric Cook: [...] > #!/bin/sh > ${ZSH_VERSION+false} : || emulate sh > match() { > test "$#" -gt 2 && return Why not "-gt 1"? > test -e "$1" && return test -e will return false for a symlink to an inaccessible file. So you'll want a test -L "$1" as well. > return 1 > } > > set -- > for pat in '..?*' '.[!.]*' '*'; do # I moved your added pattern to where > POSIX locale would sort them. > if match $pat; then > set -- "$@" $pat Note that for that to work in the Bourne shell, IFS needs to contain space (and none of the characters in the patterns in all Bourne-like shells). Another approach that only relies on reading the directory contents (not "stat"ing the files): set -- [*] * case $1$2 in '[*]*') shift 2;; *) shift esac IFS=" " set -- .[.]?* ${1+"$@"} case $1 in '.[.]?*') shift; esac set -- .[[]'!.]?*' .[!.]?* ${1+"$@"} case $1$2 in '.[[]!.]?*.[!.]?*') shift 2;; *) shift esac (won't give the same order as *(ND) either). -- Stephane ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Equivalent of set -- *(DN) in sh 2015-01-19 23:05 ` Stephane Chazelas @ 2015-01-22 7:44 ` Nikolai Weibull [not found] ` <CADdV=MsvuSAQMJVsr17Y7g2Nfjy95CQ007opQqv-7=RHjgjaKw__35342.9068615243$1421913204$gmane$org@mail.gmail.com> 1 sibling, 0 replies; 15+ messages in thread From: Nikolai Weibull @ 2015-01-22 7:44 UTC (permalink / raw) To: Eric Cook, zsh-users On Tue, Jan 20, 2015 at 12:05 AM, Stephane Chazelas <stephane.chazelas@gmail.com> wrote: > Another approach that only relies on reading the directory > contents (not "stat"ing the files): > > set -- [*] * > case $1$2 in > '[*]*') shift 2;; > *) shift > esac > IFS=" " > set -- .[.]?* ${1+"$@"} > case $1 in '.[.]?*') shift; esac > set -- .[[]'!.]?*' .[!.]?* ${1+"$@"} > case $1$2 in > '.[[]!.]?*.[!.]?*') shift 2;; > *) shift > esac > > (won't give the same order as *(ND) either). How about set x *; shift test $# -eq 1 && test "x$1" = x\* && ! test -e \* && shift n=$# set x .[!.]* ${1+"$@"}; shift test $# -eq `expr $n + 1` && test "x$1" = 'x.[!.]?*' && ! test -e '.[!.]?*' && shift n=$# set x ..?* ${1+"$@"}; shift test $# -eq `expr $n + 1` && test ="x$1" = 'x..?*' && ! test -e '..?*' && shift This tries to avoid using test -e (or whatever version of testing for a files existence you’d like to use), but also avoids using patterns just to test for failures to avoid unnecessary directory traversals. It also avoids messing with IFS, but perhaps that’s necessary? The ${1+"$@"} is to avoid an old Zsh bug, right? It also avoids set --, as that’s apparently not portable either. ^ permalink raw reply [flat|nested] 15+ messages in thread
[parent not found: <CADdV=MsvuSAQMJVsr17Y7g2Nfjy95CQ007opQqv-7=RHjgjaKw__35342.9068615243$1421913204$gmane$org@mail.gmail.com>]
* Re: Equivalent of set -- *(DN) in sh [not found] ` <CADdV=MsvuSAQMJVsr17Y7g2Nfjy95CQ007opQqv-7=RHjgjaKw__35342.9068615243$1421913204$gmane$org@mail.gmail.com> @ 2015-01-22 15:21 ` Stephane Chazelas 0 siblings, 0 replies; 15+ messages in thread From: Stephane Chazelas @ 2015-01-22 15:21 UTC (permalink / raw) To: Nikolai Weibull; +Cc: Eric Cook, zsh-users 2015-01-22 08:44:40 +0100, Nikolai Weibull: [...] > set x *; shift > test $# -eq 1 && test "x$1" = x\* && ! test -e \* && shift > n=$# > set x .[!.]* ${1+"$@"}; shift > test $# -eq `expr $n + 1` && test "x$1" = 'x.[!.]?*' && ! test -e > '.[!.]?*' && shift > n=$# > set x ..?* ${1+"$@"}; shift > test $# -eq `expr $n + 1` && test ="x$1" = 'x..?*' && ! test -e '..?*' && shift > > This tries to avoid using test -e (or whatever version of testing for > a files existence you’d like to use) Well, it doesn't try very hard does it ;-) ? Remember you need test -e || test -L (or test -h on some old systems). > but also avoids using patterns > just to test for failures to avoid unnecessary directory traversals. The directory content will be in cache after the first `set x *`. Forking and exeuting some exprs is probably going to be worse in most cases. > It also avoids messing with IFS, but perhaps that’s necessary? Well, yes "$@" in the Bourne shell relies on it containing space and you're leaving a number of variables and command substitutions unquoted. Note that "case" has far fewer problems than "test". > > The ${1+"$@"} is to avoid an old Zsh bug, right? No, that's the other way round. ${1+"$@"} is to work around problems with the Bourne shell (at least those where that has not been fixed (where "$@" expands to one empty argument when $# is 0)). zsh is the one that had problems with ${1+"$@"} (not "$@"), not really a bug, but down to how parameter expansion nested. Which is why you see things like: test -z "$ZSH_VERSION" || alias -g '${1+"$@"}="$@"' > It also avoids set --, as that’s apparently not portable either. According to http://www.in-ulm.de/~mascheck/bourne/, -- was added to the Bourne shell at the same time as [!...], so that would suggest that if you want to account for those very old systems, you can't use [!...] either. Note that old Bourne shells didn't support characters with the 8th bit set either. -- Stephane ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-01-22 15:21 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-01-18 18:28 Equivalent of set -- *(DN) in sh Nikolai Weibull 2015-01-18 19:07 ` Roman Neuhauser 2015-01-18 19:43 ` Nikolai Weibull 2015-01-18 20:32 ` Roman Neuhauser 2015-01-18 19:31 ` ZyX 2015-01-18 19:46 ` Nikolai Weibull 2015-01-18 20:46 ` Eric Cook 2015-01-19 15:51 ` ZyX 2015-01-19 15:55 ` ZyX 2015-01-19 16:02 ` ZyX 2015-01-19 16:16 ` ZyX 2015-01-19 21:44 ` Eric Cook [not found] ` <54BD7ABB.5070501__36205.2317861982$1421704010$gmane$org@gmx.com> 2015-01-19 23:05 ` Stephane Chazelas 2015-01-22 7:44 ` Nikolai Weibull [not found] ` <CADdV=MsvuSAQMJVsr17Y7g2Nfjy95CQ007opQqv-7=RHjgjaKw__35342.9068615243$1421913204$gmane$org@mail.gmail.com> 2015-01-22 15:21 ` Stephane Chazelas
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).