Skip to content

Instantly share code, notes, and snippets.

@ormaaj
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ormaaj/04923e11e8bdc27688ad to your computer and use it in GitHub Desktop.
Save ormaaj/04923e11e8bdc27688ad to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
{ code=$(</dev/fd/0); } <<\EOF
${ZSH_VERSION+false} || emulate ksh
# eval showEnv (funcname) to display the state of "x" from a subprocess.
showEnv=$'bash -c \'${x+:} typeset x=unset; printf "subprocess %s: %s\\n" "$1" "$(typeset -p x)"\' --'
function printTest {
printf '%s test %d:\n' "$1" $((testnum++)) >&2
}
function f {
# For ksh93 use a nameref in the one case where "x" is local to "g".
[[ ${!KSH_VERSION} == .sh.version && -n $1 ]] && typeset -n x=$1
typeset x='in f'
eval "$showEnv" f
printf 'local f: %s\n' "$(typeset -p x)"
}
# Test local export
function g {
typeset -x x='in g'
eval "$showEnv" g
f x
printf 'local g: %s\n' "$(typeset -p x)"
}
# Test nameref export
function h {
case ${1:-1} in
1)
typeset x='in h1'
h 2 x
eval "$showEnv" h1
printf 'local h1: %s\n' "$(typeset -p x)"
;;
2)
typeset -n _x=$2
typeset -x _x='in h2'
eval "$showEnv" h2
esac
}
testnum=1
printTest "$1"
# Export from global scope then test from local scope.
{
typeset -x x=global
f
${x+:} typeset x=unset
printf 'global: %s\n' "$(typeset -p x)"
} | sed 's/^/ /' # indent test output for clarity.
printTest "$1"
# Export from local scope then test from a child scope.
{
g
${x+:} typeset x=unset
printf 'global: %s\n' "$(typeset -p x)"
} | sed 's/^/ /'
printTest "$1"
# Test exporting variables by reference. (Should this even work?)
{
${ZSH_VERSION+false} || exit 0
h 1
} | sed 's/^/ /'
EOF
for sh in bash ksh mksh zsh; do
printf '%s\n\n' "$("$sh" -c "$code" -- "$sh" 2>&1)"
done
# vim: set fenc=utf-8 ff=unix ft=sh :
bash test 1:
subprocess f: declare -x x="in f"
local f: declare -x x="in f"
global: declare -x x="global"
bash test 2:
subprocess g: declare -x x="in g"
subprocess f: declare -x x="in f"
local f: declare -x x="in f"
local g: declare -x x="in g"
global: declare -- x="unset"
bash test 3:
subprocess h2: declare -- x="unset"
subprocess h1: declare -- x="unset"
local h1: declare -- x="in h1"
ksh test 1:
subprocess f: declare -- x="unset"
local f: x='in f'
global: typeset -x x=global
ksh test 2:
subprocess g: declare -x x="in g"
subprocess f: declare -- x="unset"
local f: typeset -n x=x
local g: x='in f'
global: x=unset
ksh test 3:
subprocess h2: declare -- x="unset"
subprocess h1: declare -x x="in h2"
local h1: typeset -x x='in h2'
mksh test 1:
subprocess f: declare -x x="global"
local f: typeset x='in f'
global: typeset -x x=global
mksh test 2:
subprocess g: declare -x x="in g"
subprocess f: declare -x x="in g"
local f: typeset x='in f'
local g: typeset -x x='in g'
global: typeset x=unset
mksh test 3:
subprocess h2: declare -x x="in h2"
subprocess h1: declare -- x="unset"
local h1: typeset x='in h1'
zsh test 1:
subprocess f: declare -- x="unset"
local f: typeset x='in f'
global: typeset -x x=global
zsh test 2:
subprocess g: declare -x x="in g"
subprocess f: declare -- x="unset"
local f: typeset x='in f'
local g: typeset -x x='in g'
global: typeset x=unset
zsh test 3:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment