Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Setting GLOB_DOTS for a single command

Hello all!

I recently learned about GLOB_DOTS, which is pretty useful in some scenarios, e.g.

echo *(md-1)

To show all files modified within the last day.  However, in some cases I want to see hidden files (e.g. ./.foo) as well.  The globdots option is excellent for this!

Is there an easy way to set this for a single _expression_?

I know I can use a function / anonymous function combined with LOCAL_OPTIONS to get this, but I wondered if there's something more clever.

    show() {
        setopt | grep glob

    echo ----- Before -----

        setopt globdots
        echo ----- Inside -----
        setopt localoptions

    echo ----- After -----

I expect that there's something I can do for scripts that I fully control, to declare some function ('globdots') which is invoked with noglob, and can then internally set the flag, and then trigger expansion of each argument in "$@".  

    globdots() {
        setopt globdots
        local arguments=( $@ ) # TODO: Force filename expansion on each item in ${@} or ${arguments[@]}
        setopt localoptions

    touch .hidden_file

    # Does NOT show .hidden_file
    ls -1d *(md-1)

    # DOES show .hidden_file
    noglob globdots ls -1d *(md-1)

However, I'm not sure what portion of Section 14 (Expansion) to read to figure out how that works.  It initially looked like the (e) flag (per would do this, but it doesn't appear to.  

I can just invoke "eval" on something that I KNOW will be a glob _expression_ to get it to expand, but blindly calling eval will execute things that are NOT glob expressions, and I only want filename expansion.

What I have found that DOES work (but overkill and a hack) is just to shell out to zsh again, while passing in all options that are currently set -- plus globdots.

    () {
        set -x
        yo() {
            local myopts=( $(setopt) globdots )
            local myargs=()
            local arg
            for arg in "$@"; do
                myargs+=( "$(zsh -c "setopt $o &>/dev/null; command echo $arg" )" )
        touch .hidden_file
        noglob yo echo *hidden*(mm-1)

This of course is wasteful, and I expect there's a better solution.

Then there's also the issue of causing filename expansion to occur when unintended -- for example, if '*' is indeed just a string argument, and should not be subject to expansion.  I think this corner case I can ignore, as any user will explicitly be asking for glob expansion.

Finally, I wanted to say that I genuinely appreciate the help and answers I've gotten from this community.  You're all very welcoming, experienced, and get down to the point / answers quickly.  If there's any way that I can help support Zsh development or the community around it, please let me know.

Zach Riggle

Messages sorted by: Reverse Date, Date, Thread, Author