Skip to content

Instantly share code, notes, and snippets.

@ormaaj
Last active March 31, 2026 16:52
Show Gist options
  • Select an option

  • Save ormaaj/eebc14c6aab3309b5efd914cd0cc1123 to your computer and use it in GitHub Desktop.

Select an option

Save ormaaj/eebc14c6aab3309b5efd914cd0cc1123 to your computer and use it in GitHub Desktop.
nameref chaining and dangling namerefs
{ exename=$(python3) exename=${exename%%?} || exit; } <<\EOF
import os, sys
try:
        fd = os.open(os.path.join(b"/proc", os.fsencode(str(os.getppid())), b"exe"), os.O_PATH | os.O_NOFOLLOW)
        sys.stdout.buffer.write(os.path.basename(os.readlink(b"", dir_fd = fd)).__add__(b"\x01"))
except: sys.exit(1)
finally: os.close(fd)
EOF
case $exename in
        bash)
                shopt -s lastpipe extglob expand_aliases
                typeset -gx BASH_COMPAT=51
                ;;
        ksh)
                [[ $KSH_VERSION == *93v-* ]] ||
                        set -o posix
                ;;
        zsh) emulate ksh
esac

# zsh -> `-g`
# bash >= 5.3 -> `-G`
# else drop the attribute and return nonzero
function nonlocal_alias {
        typeset s=0
        [[
                ! -v ZSH_VERSION &&
                '(BASH_VERSINFO[0] >= 6 || (BASH_VERSINFO[0] >= 5 && BASH_VERSINFO[1] >= 3)) ? ++s : 0' -ne 0
        ]] || unset -v s
        printf -v s %b ${s+" -\\x$((67 - s * 20))"}
        alias "nonlocal=typeset${s}"
        return "$((${s+!}1))"
}; nonlocal_alias

function m1 {
        typeset -t a=b b=c c
        trap 'typeset -p a b c 2>/dev/null && echo' DEBUG
        nonlocal -n a; nonlocal -n a; nonlocal +t a
        nonlocal +n a
        typeset +n a
        trap - DEBUG
}

function m2 {
        typeset a=b b=c; typeset -t c
        trap 'typeset -p a b c 2>/dev/null && echo' DEBUG
        nonlocal -n a; nonlocal -n a; nonlocal -n a
        nonlocal +t a
        nonlocal +n a
        trap - DEBUG
}

alias nonlocal=typeset

function m3 {
        typeset -t a=b b=c c
        trap 'typeset -p a b c 2>/dev/null && echo' DEBUG
        nonlocal -n a; nonlocal -n a; nonlocal +t a
        nonlocal +n a
        typeset +n a
        trap - DEBUG
}

function m {
        typeset -a funcs
        typeset f
        case $exename in
                bash) compgen -V funcs -A function -X '!m[[:digit:]]' ;;
                ksh) typeset +f |
                        while LC_CTYPE=C IFS= read -r f; do
                                [[ $f == m[[:digit:]] ]] || continue
                                funcs+=("$f")
                        done
        esac
        for f in "${funcs[@]}"; do
                printf %s\\n ------- "${f}:"
                "$f"
        done
}

m
_EOF
bash:
-------
m1:
declare -t a="b"
declare -t b="c"
declare -t c

declare -nt a="b"
declare -t b="c"
declare -t c

declare -nt a="b"
declare -nt b="c"
declare -t c

declare -nt a="b"
declare -nt b="c"
declare -- c

declare -nt a="b"
declare -nt b="c"
declare -- c

declare -t a="b"
declare -nt b="c"
declare -- c

-------
m2:
declare -- a="b"
declare -- b="c"
declare -t c

declare -n a="b"
declare -- b="c"
declare -t c

declare -n a="b"
declare -n b="c"
declare -t c

declare -n a="b"
declare -n b="c"
declare -nt c

declare -n a="b"
declare -n b="c"
declare -nt c

declare -n a="b"
declare -n b="c"
declare -nt c

-------
m3:
declare -t a="b"
declare -t b="c"
declare -t c

declare -nt a="b"
declare -t b="c"
declare -t c

declare -nt a="b"
declare -t b="c"
declare -t c

declare -nt a="b"
declare -- b="c"
declare -t c

declare -t a="b"
declare -- b="c"
declare -t c

declare -t a="b"
declare -- b="c"
declare -t c

ksh:
-------
m1:
typeset -t a=b
typeset -t b=c
typeset -t c

typeset -n a=b
typeset -t b=c
typeset -t c

typeset -n a=b
typeset -n b=c
typeset -t c

typeset -n a=b
typeset -n b=c

a=b
typeset -n b=c

a=b
typeset -n b=c

-------
m2:
a=b
b=c
typeset -t c

typeset -n a=b
b=c
typeset -t c

typeset -n a=b
typeset -n b=c
typeset -t c

typeset -n a=b
typeset -n b=c
typeset -n c

typeset -n a=b
typeset -n b=c
typeset -n c

a=b
typeset -n b=c
typeset -n c

-------
m3:
typeset -t a=b
typeset -t b=c
typeset -t c

typeset -n a=b
typeset -t b=c
typeset -t c

typeset -n a=b
typeset -n b=c
typeset -t c

typeset -n a=b
typeset -n b=c

a=b
typeset -n b=c

a=b
typeset -n b=c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment