mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-19 21:44:11 +01:00
964 lines
20 KiB
Plaintext
964 lines
20 KiB
Plaintext
# Test various shell options.
|
|
# Interactive options not tested here:
|
|
# ALWAYS_LAST_PROMPT
|
|
# ALWAYS_TO_END
|
|
# APPEND_HISTORY (history not maintained)
|
|
# AUTO_LIST
|
|
# AUTO_MENU
|
|
# AUTO_NAME_DIRS (named directory table not maintained)
|
|
# AUTO_PARAM_KEYS
|
|
# AUTO_PARAM_SLASH
|
|
# AUTO_REMOVE_SLASH
|
|
# AUTO_RESUME
|
|
# BANG_HIST
|
|
# BASH_AUTO_LIST
|
|
# BEEP (!)
|
|
# BG_NICE
|
|
# CHECK_JOBS
|
|
# COMPLETE_ALIASES
|
|
# COMPLETE_IN_WORD
|
|
# CORRECT
|
|
# CORRECT_ALL
|
|
# CSH_JUNKIE_HISTORY
|
|
# DVORAK
|
|
# EXTENDED_HISTORY
|
|
# FLOW_CONTROL
|
|
# GLOB_COMPLETE
|
|
# HIST_ALLOW_CLOBBER
|
|
# HIST_BEEP
|
|
# HIST_EXPIRE_DUPS_FIRST
|
|
# HIST_FIND_NO_DUPS
|
|
# HIST_IGNORE_ALL_DUPS
|
|
# HIST_IGNORE_DUPS (-h)
|
|
# HIST_IGNORE_SPACE (-g)
|
|
# HIST_NO_FUNCTIONS
|
|
# HIST_NO_STORE
|
|
# HIST_REDUCE_BLANKS
|
|
# HIST_SAVE_NO_DUPS
|
|
# HIST_VERIFY
|
|
# HUP
|
|
# IGNORE_EOF
|
|
# INC_APPEND_HISTORY
|
|
# INTERACTIVE
|
|
# INTERACTIVE_COMMENTS
|
|
# LIST_AMBIGUOUS
|
|
# LIST_BEEP
|
|
# LIST_PACKED
|
|
# LIST_ROWS_FIRST
|
|
# LIST_TYPES
|
|
# LOGIN
|
|
# LONG_LIST_JOBS
|
|
# MAIL_WARNING
|
|
# MENU_COMPLETE
|
|
# MONITOR
|
|
# NOTIFY
|
|
# OVERSTRIKE
|
|
# PRINT_EIGHT_BIT
|
|
# PROMPT_CR
|
|
# PUSHD_SILENT
|
|
# REC_EXACT
|
|
# RM_STAR_SILENT
|
|
# RM_STAR_WAIT
|
|
# SHARE_HISTORY
|
|
# SINGLE_LINE_ZLE
|
|
# SUN_KEYBOARD_HACK
|
|
# ZLE
|
|
# The following require SHINSTDIN and are not (yet) tested:
|
|
# AUTO_CD
|
|
# SHINSTDIN
|
|
#
|
|
# Other difficult things I haven't done:
|
|
# GLOBAL_RCS (uses fixed files outside build area)
|
|
# HASH_CMDS )
|
|
# HASH_DIRS ) fairly seriously internal, hard to test at all
|
|
# HASH_LIST_ALL )
|
|
# PRINT_EXIT_STATUS haven't worked out what this does yet, although
|
|
# Bart suggested a fix.
|
|
# PRIVILEGED (similar to GLOBAL_RCS)
|
|
# RCS ( " " " " )
|
|
# SH_OPTION_LETTERS even I found this too dull to set up a test for
|
|
# SINGLE_COMMAND kills shell
|
|
# VERBOSE hard because done on input (c.f. SHINSTDIN).
|
|
|
|
%prep
|
|
mkdir options.tmp && cd options.tmp
|
|
|
|
mkdir tmpcd
|
|
|
|
touch tmpfile1 tmpfile2
|
|
|
|
mydir=$PWD
|
|
mydirt=`print -P %~`
|
|
catpath=$(which cat)
|
|
lspath==ls
|
|
|
|
%test
|
|
|
|
alias echo='print foo'
|
|
unsetopt aliases
|
|
# use eval else aliases are all parsed at start
|
|
eval echo bar
|
|
setopt aliases
|
|
eval echo bar
|
|
unalias echo
|
|
0:ALIASES option
|
|
>bar
|
|
>foo bar
|
|
|
|
setopt allexport
|
|
testpm1=exported
|
|
unsetopt allexport
|
|
testpm2=unexported
|
|
print ${(t)testpm1}
|
|
print ${(t)testpm2}
|
|
0:ALL_EXPORT option
|
|
>scalar-export
|
|
>scalar
|
|
|
|
# Count the number of directories on the stack. Don't care what they are.
|
|
dircount() { dirs -v | tail -1 | awk '{ print $1 + 1}'; }
|
|
unsetopt autopushd
|
|
cd tmpcd
|
|
dircount
|
|
cd ..
|
|
setopt autopushd
|
|
cd tmpcd
|
|
dircount
|
|
unsetopt autopushd
|
|
popd >/dev/null
|
|
0:AUTO_PUSHD option
|
|
>1
|
|
>2
|
|
|
|
unsetopt badpattern
|
|
print [a
|
|
setopt badpattern
|
|
print [b
|
|
1:BAD_PATTERN option
|
|
>[a
|
|
?(eval):4: bad pattern: [b
|
|
|
|
unsetopt bareglobqual nomatch
|
|
print *(.)
|
|
setopt bareglobqual nomatch
|
|
print *(.)
|
|
0:BARE_GLOB_QUAL option
|
|
>*(.)
|
|
>tmpfile1 tmpfile2
|
|
|
|
setopt braceccl
|
|
print {abcd}
|
|
unsetopt braceccl
|
|
print {abcd}
|
|
0:BRACE_CCL option
|
|
>a b c d
|
|
>{abcd}
|
|
|
|
setopt bsdecho
|
|
echo "histon\nimpington"
|
|
echo -e "girton\ncottenham"
|
|
unsetopt bsdecho
|
|
echo "newnham\ncomberton"
|
|
0:BSD_ECHO option
|
|
>histon\nimpington
|
|
>girton
|
|
>cottenham
|
|
>newnham
|
|
>comberton
|
|
|
|
unsetopt c_bases
|
|
print $(( [#16]15 ))
|
|
print $(( [#8]9 ))
|
|
setopt c_bases
|
|
print $(( [#16]31 ))
|
|
print $(( [#8]17 ))
|
|
setopt octal_zeroes
|
|
print $(( [#8]19 ))
|
|
unsetopt c_bases octal_zeroes
|
|
0:C_BASES option
|
|
>16#F
|
|
>8#11
|
|
>0x1F
|
|
>8#21
|
|
>023
|
|
|
|
setopt cdablevars
|
|
# only absolute paths are eligible for ~-expansion
|
|
cdablevar1=tmpcd
|
|
(cd cdablevar1)
|
|
cdablevar2=$PWD/tmpcd
|
|
cd cdablevar2
|
|
cd ..
|
|
print back in ${PWD:t}
|
|
unsetopt cdablevars
|
|
cd cdablevar2
|
|
1q:CDABLE_VARS option
|
|
>back in options.tmp
|
|
?(eval):cd:4: no such file or directory: cdablevar1
|
|
?(eval):cd:10: no such file or directory: cdablevar2
|
|
|
|
# CHASE_DOTS should go with CHASE_LINKS in B01cd.ztst
|
|
# which saves me having to write it here.
|
|
|
|
setopt noclobber
|
|
rm -f foo1 bar1 rod1
|
|
echo waterbeach >foo1
|
|
(echo landbeach >foo1)
|
|
cat foo1
|
|
(echo lode >>bar1)
|
|
[[ -f bar1 ]] && print That shouldn\'t be there.
|
|
echo denny >rod1
|
|
echo wicken >>rod1
|
|
cat rod1
|
|
unsetopt noclobber
|
|
rm -f foo2 bar2 rod2
|
|
echo ely >foo2
|
|
echo march >foo2
|
|
cat foo2
|
|
echo wimpole >>bar2
|
|
cat bar2
|
|
echo royston >rod2
|
|
echo foxton >>rod2
|
|
cat rod2
|
|
rm -f foo* bar* rod*
|
|
0:CLOBBER option
|
|
>waterbeach
|
|
>denny
|
|
>wicken
|
|
>march
|
|
>wimpole
|
|
>royston
|
|
>foxton
|
|
?(eval):4: file exists: foo1
|
|
?(eval):6: no such file or directory: bar1
|
|
|
|
setopt cshjunkieloops
|
|
eval 'for f in swaffham bulbeck; print $f; end'
|
|
print next one should fail >&2
|
|
unsetopt cshjunkieloops
|
|
eval 'for f in chesterton arbury; print $f; end'
|
|
1:CSH_JUNKIE_LOOPS option (for loop)
|
|
>swaffham
|
|
>bulbeck
|
|
?next one should fail
|
|
?(eval):1: parse error near `end'
|
|
|
|
setopt cshjunkiequotes
|
|
print this should cause an error >&2
|
|
eval "print 'line one
|
|
line two'"
|
|
print this should not >&2
|
|
eval "print 'line three\\
|
|
line four'"
|
|
unsetopt cshjunkiequotes
|
|
0:CSH_JUNKIE_QUOTES option
|
|
>line three
|
|
> line four
|
|
?this should cause an error
|
|
?(eval):1: unmatched '
|
|
?this should not
|
|
|
|
nullcmd() { print '$NULLCMD run'; }
|
|
readnullcmd() { print 'Running $READNULLCMD'; cat; }
|
|
NULLCMD=nullcmd
|
|
READNULLCMD=readnullcmd
|
|
setopt cshnullcmd
|
|
rm -f foo
|
|
print "This should fail" >&2
|
|
(>foo)
|
|
print "This should succeed" >&2
|
|
print "These are the contents of foo" >foo
|
|
cat foo
|
|
print "This should also fail" >&2
|
|
(<foo)
|
|
unsetopt cshnullcmd
|
|
rm -f foo
|
|
>foo
|
|
<foo
|
|
rm -f foo
|
|
0:CSH_NULL_CMD option
|
|
>These are the contents of foo
|
|
>Running $READNULLCMD
|
|
>$NULLCMD run
|
|
?This should fail
|
|
?(eval):8: redirection with no command
|
|
?This should succeed
|
|
?This should also fail
|
|
?(eval):13: redirection with no command
|
|
|
|
# nomatch should be overridden by cshnullglob
|
|
setopt nomatch cshnullglob
|
|
print tmp* nothing* blah
|
|
print -n 'hoping for no match: ' >&2
|
|
(print nothing* blah)
|
|
print >&2
|
|
unsetopt cshnullglob nomatch
|
|
print tmp* nothing* blah
|
|
print nothing* blah
|
|
0:CSH_NULL_GLOB option
|
|
>tmpcd tmpfile1 tmpfile2 blah
|
|
>tmpcd tmpfile1 tmpfile2 nothing* blah
|
|
>nothing* blah
|
|
?hoping for no match: (eval):4: no match
|
|
?
|
|
|
|
# The trick is to avoid =cat being expanded in the output while $catpath is.
|
|
setopt NO_equals
|
|
print -n trick; print =cat
|
|
setopt equals
|
|
print -n trick; print =cat
|
|
0q:EQUALS option
|
|
>trick=cat
|
|
>trick$catpath
|
|
|
|
# explanation of expected TRAPZERR output: from false and from
|
|
# testfn() with ERR_EXIT on (hmm, should we really get a second one from
|
|
# the function exiting?), then from the false only with ERR_EXIT off.
|
|
TRAPZERR() { print ZERR trapped; }
|
|
testfn() { setopt localoptions $2; print $1 before; false; print $1 after; }
|
|
(testfn on errexit)
|
|
testfn off
|
|
unfunction TRAPZERR testfn
|
|
0:ERR_EXIT option
|
|
>on before
|
|
>ZERR trapped
|
|
>ZERR trapped
|
|
>off before
|
|
>ZERR trapped
|
|
>off after
|
|
|
|
(print before; setopt noexec; print after)
|
|
0:NO_EXEC option
|
|
>before
|
|
|
|
# The EXTENDED_GLOB test doesn't test globbing fully --- it just tests
|
|
# that certain patterns are treated literally with the option off
|
|
# and as patterns with the option on.
|
|
testfn() { print -n "$1 $2 $3 "; if [[ $1 = ${~2} ]];
|
|
then print yes; else print no; fi; }
|
|
tests=('a#' '?~b' '^aa')
|
|
strings=('a' 'aa' 'b' 'a#' '?~b' '^aa')
|
|
for opt in noextendedglob extendedglob; do
|
|
setopt $opt
|
|
for test in $tests; do
|
|
for string in $strings; do
|
|
testfn $string $test $opt
|
|
done
|
|
done
|
|
done
|
|
0:EXTENDED_GLOB option
|
|
>a a# noextendedglob no
|
|
>aa a# noextendedglob no
|
|
>b a# noextendedglob no
|
|
>a# a# noextendedglob yes
|
|
>?~b a# noextendedglob no
|
|
>^aa a# noextendedglob no
|
|
>a ?~b noextendedglob no
|
|
>aa ?~b noextendedglob no
|
|
>b ?~b noextendedglob no
|
|
>a# ?~b noextendedglob no
|
|
>?~b ?~b noextendedglob yes
|
|
>^aa ?~b noextendedglob no
|
|
>a ^aa noextendedglob no
|
|
>aa ^aa noextendedglob no
|
|
>b ^aa noextendedglob no
|
|
>a# ^aa noextendedglob no
|
|
>?~b ^aa noextendedglob no
|
|
>^aa ^aa noextendedglob yes
|
|
>a a# extendedglob yes
|
|
>aa a# extendedglob yes
|
|
>b a# extendedglob no
|
|
>a# a# extendedglob no
|
|
>?~b a# extendedglob no
|
|
>^aa a# extendedglob no
|
|
>a ?~b extendedglob yes
|
|
>aa ?~b extendedglob no
|
|
>b ?~b extendedglob no
|
|
>a# ?~b extendedglob no
|
|
>?~b ?~b extendedglob no
|
|
>^aa ?~b extendedglob no
|
|
>a ^aa extendedglob yes
|
|
>aa ^aa extendedglob no
|
|
>b ^aa extendedglob yes
|
|
>a# ^aa extendedglob yes
|
|
>?~b ^aa extendedglob yes
|
|
>^aa ^aa extendedglob yes
|
|
|
|
foo() { print My name is $0; }
|
|
unsetopt functionargzero
|
|
foo
|
|
setopt functionargzero
|
|
foo
|
|
unfunction foo
|
|
0:FUNCTION_ARGZERO option
|
|
>My name is ZTST_execchunk
|
|
>My name is foo
|
|
|
|
setopt _NO_glob_
|
|
print tmp*
|
|
set -o glob
|
|
print tmp*
|
|
0:GLOB option
|
|
>tmp*
|
|
>tmpcd tmpfile1 tmpfile2
|
|
|
|
showit() { local v;
|
|
for v in first second third; do
|
|
eval print \$$v \$\{\(t\)$v\}
|
|
done;
|
|
}
|
|
setit() { typeset -x first=inside1;
|
|
typeset +g -x second=inside2;
|
|
typeset -g -x third=inside3;
|
|
showit;
|
|
}
|
|
first=outside1 second=outside2 third=outside3
|
|
unsetopt globalexport
|
|
setit
|
|
showit
|
|
setopt globalexport
|
|
setit
|
|
showit
|
|
unfunction setit showit
|
|
0:GLOBAL_EXPORT option
|
|
>inside1 scalar-local-export
|
|
>inside2 scalar-local-export
|
|
>inside3 scalar-export
|
|
>outside1 scalar
|
|
>outside2 scalar
|
|
>inside3 scalar-export
|
|
>inside1 scalar-export
|
|
>inside2 scalar-local-export
|
|
>inside3 scalar-export
|
|
>inside1 scalar-export
|
|
>outside2 scalar
|
|
>inside3 scalar-export
|
|
|
|
setopt globassign
|
|
foo=tmp*
|
|
print $foo
|
|
unsetopt globassign
|
|
foo=tmp*
|
|
print $foo
|
|
0:GLOB_ASSIGN option
|
|
>tmpcd tmpfile1 tmpfile2
|
|
>tmp*
|
|
|
|
mkdir onlysomefiles
|
|
touch onlysomefiles/.thisfile onlysomefiles/thatfile
|
|
setopt globdots
|
|
print onlysomefiles/*
|
|
unsetopt globdots
|
|
print onlysomefiles/*
|
|
rm -rf onlysomefiles
|
|
0:GLOB_DOTS option
|
|
>onlysomefiles/.thisfile onlysomefiles/thatfile
|
|
>onlysomefiles/thatfile
|
|
|
|
# we've tested this enough times already...
|
|
# could add some stuff for other sorts of expansion
|
|
foo='tmp*'
|
|
setopt globsubst
|
|
print ${foo}
|
|
unsetopt globsubst
|
|
print ${foo}
|
|
0:GLOB_SUBST option
|
|
>tmpcd tmpfile1 tmpfile2
|
|
>tmp*
|
|
|
|
setopt ignorebraces
|
|
echo X{a,b}Y
|
|
unsetopt ignorebraces
|
|
echo X{a,b}Y
|
|
0:IGNORE_BRACES option
|
|
>X{a,b}Y
|
|
>XaY XbY
|
|
|
|
setopt ksh_arrays
|
|
array=(one two three)
|
|
print $array $array[2]
|
|
print ${array[0]} ${array[1]} ${array[2]} ${array[3]}
|
|
unsetopt ksh_arrays
|
|
print $array $array[2]
|
|
print ${array[0]} ${array[1]} ${array[2]} ${array[3]}
|
|
unset array
|
|
0:KSH_ARRAYS option
|
|
>one one[2]
|
|
>one two three
|
|
>one two three two
|
|
>one one two three
|
|
|
|
fpath=(.)
|
|
echo >foo 'echo foo loaded; foo() { echo foo run; }'
|
|
echo >bar 'bar() { echo bar run; }'
|
|
setopt kshautoload
|
|
autoload foo bar
|
|
foo
|
|
bar
|
|
unfunction foo bar
|
|
unsetopt kshautoload
|
|
autoload foo bar
|
|
foo
|
|
bar
|
|
0:KSH_AUTOLOAD option
|
|
>foo loaded
|
|
>foo run
|
|
>bar run
|
|
>foo loaded
|
|
>bar run
|
|
|
|
# ksh_glob is tested by the glob tests.
|
|
|
|
setopt kshoptionprint globassign
|
|
print set
|
|
setopt | grep kshoptionprint
|
|
setopt | grep globassign
|
|
unsetopt kshoptionprint
|
|
print unset
|
|
setopt | grep kshoptionprint
|
|
setopt | grep globassign
|
|
unsetopt globassign
|
|
0:KSH_OPTION_PRINT option
|
|
>set
|
|
>kshoptionprint on
|
|
>globassign on
|
|
>unset
|
|
>globassign
|
|
|
|
setopt kshtypeset
|
|
ktvars=(ktv1 ktv2)
|
|
typeset ktfoo=`echo arg1 arg2` $ktvars
|
|
print $+ktv1 $+ktv2 $+ktv3
|
|
print $ktfoo
|
|
unsetopt kshtypeset
|
|
typeset noktfoo=`echo noktarg1 noktarg2`
|
|
print $noktfoo
|
|
print $+noktarg1 $+noktarg2
|
|
unset ktfoo ktv1 ktv2 noktfoo noktarg2
|
|
0:KSH_TYPESET option
|
|
>1 1 0
|
|
>arg1 arg2
|
|
>noktarg1
|
|
>0 1
|
|
|
|
showopt() { setopt | egrep 'localoptions|ksharrays'; }
|
|
f1() { setopt localoptions ksharrays; showopt }
|
|
f2() { setopt ksharrays; showopt }
|
|
setopt kshoptionprint
|
|
showopt
|
|
f1
|
|
showopt
|
|
f2
|
|
showopt
|
|
unsetopt ksh_arrays
|
|
0:LOCAL_OPTIONS option
|
|
>ksharrays off
|
|
>localoptions off
|
|
>ksharrays on
|
|
>localoptions on
|
|
>ksharrays off
|
|
>localoptions off
|
|
>ksharrays on
|
|
>localoptions off
|
|
>ksharrays on
|
|
>localoptions off
|
|
|
|
# LOCAL_TRAPS was tested in C03traps (phew).
|
|
|
|
fn() {
|
|
local HOME=/any/old/name
|
|
print -l var=~ 'anything goes/here'=~ split=`echo maybe not`;
|
|
}
|
|
setopt magicequalsubst
|
|
fn
|
|
setopt kshtypeset
|
|
fn
|
|
unsetopt magicequalsubst kshtypeset
|
|
fn
|
|
0:MAGIC_EQUAL_SUBST option
|
|
>var=/any/old/name
|
|
>anything goes/here=/any/old/name
|
|
>split=maybe
|
|
>not
|
|
>var=/any/old/name
|
|
>anything goes/here=/any/old/name
|
|
>split=maybe not
|
|
>var=~
|
|
>anything goes/here=~
|
|
>split=maybe
|
|
>not
|
|
|
|
setopt MARK_DIRS
|
|
print tmp*
|
|
unsetopt MARK_DIRS
|
|
print tmp*
|
|
0:MARK_DIRS option
|
|
>tmpcd/ tmpfile1 tmpfile2
|
|
>tmpcd tmpfile1 tmpfile2
|
|
|
|
# maybe should be in A04redirect
|
|
print "This is in1" >in1
|
|
print "This is in2" >in2
|
|
unsetopt multios
|
|
print Test message >foo1 >foo2
|
|
print foo1: $(<foo1)
|
|
print foo2: $(<foo2)
|
|
cat <in1 <in2
|
|
setopt multios
|
|
print Test message >foo1 >foo2
|
|
sleep 1 # damn, race in multios
|
|
print foo1: $(<foo1)
|
|
print foo2: $(<foo2)
|
|
cat <in1 <in2
|
|
rm -f foo1 foo2 in1 in2
|
|
0:MULTIOS option
|
|
>foo1:
|
|
>foo2: Test message
|
|
>This is in2
|
|
>foo1: Test message
|
|
>foo2: Test message
|
|
>This is in1
|
|
>This is in2
|
|
|
|
# tried this with other things, but not on its own, so much.
|
|
unsetopt nomatch
|
|
print with nonomatch: flooble*
|
|
setopt nomatch
|
|
print with nomatch flooble*
|
|
1:NOMATCH option
|
|
>with nonomatch: flooble*
|
|
?(eval):4: no matches found: flooble*
|
|
|
|
# NULL_GLOB should override NONOMATCH...
|
|
setopt nullglob nomatch
|
|
print frooble* tmp*
|
|
unsetopt nullglob nomatch
|
|
print frooble* tmp*
|
|
0:NULL_GLOB option
|
|
>tmpcd tmpfile1 tmpfile2
|
|
>frooble* tmpcd tmpfile1 tmpfile2
|
|
|
|
touch ngs1.txt ngs2.txt ngs10.txt ngs20.txt ngs100.txt ngs200.txt
|
|
setopt numericglobsort
|
|
print -l ngs*
|
|
unsetopt numericglobsort
|
|
print -l ngs*
|
|
0:NUMERIC_GLOB_SORT option
|
|
>ngs1.txt
|
|
>ngs2.txt
|
|
>ngs10.txt
|
|
>ngs20.txt
|
|
>ngs100.txt
|
|
>ngs200.txt
|
|
>ngs1.txt
|
|
>ngs10.txt
|
|
>ngs100.txt
|
|
>ngs2.txt
|
|
>ngs20.txt
|
|
>ngs200.txt
|
|
|
|
typeset -i 10 oznum
|
|
setopt octalzeroes
|
|
(( oznum = 012 + 013 ))
|
|
print $oznum
|
|
unsetopt octalzeroes
|
|
(( oznum = 012 + 013 ))
|
|
print $oznum
|
|
unset oznum
|
|
0:OCTAL_ZEROES options
|
|
>21
|
|
>25
|
|
|
|
typeset -a oldpath
|
|
oldpath=($path)
|
|
mkdir pdt_topdir pathtestdir pdt_topdir/pathtestdir
|
|
print "#!/bin/sh\necho File in upper dir" >pathtestdir/findme
|
|
print "#!/bin/sh\necho File in lower dir" >pdt_topdir/pathtestdir/findme
|
|
chmod u+x pathtestdir/findme pdt_topdir/pathtestdir/findme
|
|
pathtestdir/findme
|
|
rm -f pathtestdir/findme
|
|
setopt pathdirs
|
|
path=($PWD $PWD/pdt_topdir)
|
|
pathtestdir/findme
|
|
print unsetting option...
|
|
unsetopt pathdirs
|
|
pathtestdir/findme
|
|
path=($oldpath)
|
|
unset $oldpath
|
|
rm -rf pdt_topdir pathtestdir
|
|
0:PATH_DIRS option
|
|
>File in upper dir
|
|
>File in lower dir
|
|
>unsetting option...
|
|
?(eval):14: no such file or directory: pathtestdir/findme
|
|
|
|
setopt posixbuiltins
|
|
PATH= command print foo
|
|
unsetopt posixbuiltins
|
|
print unsetting...
|
|
PATH= command print foo
|
|
127:POSIX_BUILTINS option
|
|
>foo
|
|
>unsetting...
|
|
?(eval):5: command not found: print
|
|
|
|
# This option seems to be problematic. I don't quite know how it works.
|
|
## func() {
|
|
## setopt localoptions printexitvalue
|
|
## false
|
|
## }
|
|
## func
|
|
## 1:PRINT_EXIT_VALUE option
|
|
## ?(eval):2: exit 1
|
|
|
|
setopt promptbang
|
|
print -P !
|
|
setopt nopromptbang
|
|
print -P !
|
|
0:PROMPT_BANG option
|
|
>0
|
|
>!
|
|
|
|
unsetopt promptpercent
|
|
print -P '%/'
|
|
setopt promptpercent
|
|
print -P '%/'
|
|
0q:PROMPT_PERCENT option
|
|
>%/
|
|
>$mydir
|
|
|
|
setopt promptsubst
|
|
print -P '`echo waaah`'
|
|
unsetopt promptsubst
|
|
print -P '`echo waaah`'
|
|
0:PROMPT_SUBST option
|
|
>waaah
|
|
>`echo waaah`
|
|
|
|
dirs
|
|
pushd $mydir/tmpcd
|
|
dirs
|
|
pushd $mydir/tmpcd
|
|
dirs
|
|
setopt pushdignoredups
|
|
pushd $mydir/tmpcd
|
|
dirs
|
|
unsetopt pushdignoredups
|
|
popd >/dev/null
|
|
popd >/dev/null
|
|
0q:PUSHD_IGNOREDUPS option
|
|
>$mydirt
|
|
>$mydirt/tmpcd $mydirt
|
|
>$mydirt/tmpcd $mydirt/tmpcd $mydirt
|
|
>$mydirt/tmpcd $mydirt/tmpcd $mydirt
|
|
|
|
mkdir newcd
|
|
cd $mydir
|
|
pushd $mydir/tmpcd
|
|
pushd $mydir/newcd
|
|
dirs
|
|
pushd -0
|
|
dirs
|
|
setopt pushdminus pushdsilent
|
|
pushd -0
|
|
dirs
|
|
unsetopt pushdminus
|
|
popd >/dev/null
|
|
popd >/dev/null
|
|
cd $mydir
|
|
0q:PUSHD_MINUS option
|
|
>$mydirt/newcd $mydirt/tmpcd $mydirt
|
|
>$mydirt $mydirt/newcd $mydirt/tmpcd
|
|
>$mydirt $mydirt/newcd $mydirt/tmpcd
|
|
|
|
# Do you have any idea how dull this is?
|
|
|
|
pushd $mydir/tmpcd
|
|
pushd
|
|
dirs
|
|
setopt pushdtohome
|
|
pushd
|
|
dirs
|
|
unsetopt pushdtohome
|
|
popd
|
|
pushd
|
|
popd
|
|
dirs
|
|
0q:PUSHD_TO_HOME option
|
|
>$mydirt $mydirt/tmpcd
|
|
>~ $mydirt $mydirt/tmpcd
|
|
>$mydirt
|
|
|
|
array=(one two three four)
|
|
setopt rcexpandparam
|
|
print aa${array}bb
|
|
unsetopt rcexpandparam
|
|
print aa${array}bb
|
|
0:RC_EXPAND_PARAM option
|
|
>aaonebb aatwobb aathreebb aafourbb
|
|
>aaone two three fourbb
|
|
|
|
setopt rcquotes
|
|
# careful, this is done when parsing a complete block
|
|
eval "print 'one''quoted''expression'"
|
|
unsetopt rcquotes
|
|
eval "print 'another''quoted''expression'"
|
|
0:RC_QUOTES option
|
|
>one'quoted'expression
|
|
>anotherquotedexpression
|
|
|
|
# too lazy to test jobs -Z and ARGV0.
|
|
(setopt restricted; cd /)
|
|
(setopt restricted; PATH=/bin:/usr/bin)
|
|
(setopt restricted; /bin/ls)
|
|
(setopt restricted; hash ls=/bin/ls)
|
|
(setopt restricted; print ha >outputfile)
|
|
(setopt restricted; exec ls)
|
|
(setopt restricted; unsetopt restricted)
|
|
:
|
|
0:RESTRICTED option
|
|
?(eval):cd:1: restricted
|
|
?(eval):2: PATH: restricted
|
|
?(eval):3: /bin/ls: restricted
|
|
?(eval):hash:4: restricted: /bin/ls
|
|
?(eval):5: writing redirection not allowed in restricted mode
|
|
?(eval):exec:6: ls: restricted
|
|
?(eval):unsetopt:7: can't change option: restricted
|
|
|
|
fn() {
|
|
print =ls ={ls,}
|
|
local foo='=ls'
|
|
print ${~foo}
|
|
}
|
|
setopt shfileexpansion
|
|
fn
|
|
unsetopt shfileexpansion
|
|
fn
|
|
0q:SH_FILE_EXPANSION option
|
|
>$lspath =ls =
|
|
>=ls
|
|
>$lspath $lspath =
|
|
>$lspath
|
|
|
|
testpat() {
|
|
if [[ $1 = ${~2} ]]; then print $1 $2 yes; else print $1 $2 no; fi
|
|
}
|
|
print option on
|
|
setopt shglob
|
|
repeat 2; do
|
|
for str in 'a(b|c)' ab; do
|
|
testpat $str 'a(b|c)'
|
|
done
|
|
for str in 'a<1-10>' a9; do
|
|
testpat $str 'a<1-10>'
|
|
done
|
|
[[ ! -o shglob ]] && break
|
|
print option off
|
|
unsetopt shglob
|
|
done
|
|
0:SH_GLOB option
|
|
>option on
|
|
>a(b|c) a(b|c) yes
|
|
>ab a(b|c) no
|
|
>a<1-10> a<1-10> yes
|
|
>a9 a<1-10> no
|
|
>option off
|
|
>a(b|c) a(b|c) no
|
|
>ab a(b|c) yes
|
|
>a<1-10> a<1-10> no
|
|
>a9 a<1-10> yes
|
|
|
|
print this is bar >bar
|
|
fn() {
|
|
local NULLCMD=cat READNULLCMD=cat
|
|
echo hello | >foo
|
|
cat foo
|
|
<bar
|
|
}
|
|
setopt shnullcmd
|
|
print option set
|
|
fn
|
|
unsetopt shnullcmd
|
|
print option unset
|
|
fn
|
|
rm -f foo bar
|
|
0:SH_NULLCMD option
|
|
>option set
|
|
>option unset
|
|
>hello
|
|
>this is bar
|
|
|
|
fn() {
|
|
eval 'for f in foo bar; print $f'
|
|
eval 'for f (word1 word2) print $f'
|
|
eval 'repeat 3 print nonsense'
|
|
}
|
|
unsetopt shortloops
|
|
print option unset
|
|
fn
|
|
setopt shortloops
|
|
print option set
|
|
fn
|
|
0:SHORT_LOOPS option
|
|
>option unset
|
|
>option set
|
|
>foo
|
|
>bar
|
|
>word1
|
|
>word2
|
|
>nonsense
|
|
>nonsense
|
|
>nonsense
|
|
?(eval):1: parse error near `print'
|
|
?(eval):1: parse error near `print'
|
|
?(eval):1: parse error near `print'
|
|
|
|
fn() { print -l $*; }
|
|
setopt shwordsplit
|
|
print option set
|
|
repeat 2; do
|
|
foo='two words'
|
|
fn $foo
|
|
fn "${=foo}"
|
|
[[ ! -o shwordsplit ]] && break
|
|
unsetopt shwordsplit
|
|
print option unset
|
|
done
|
|
0:SH_WORD_SPLIT option
|
|
>option set
|
|
>two
|
|
>words
|
|
>two
|
|
>words
|
|
>option unset
|
|
>two words
|
|
>two
|
|
>words
|
|
|
|
fn() { unset foo; print $foo; }
|
|
setopt nounset
|
|
print option unset unset by setting nounset
|
|
eval fn
|
|
print option unset reset
|
|
setopt unset
|
|
fn
|
|
0:UNSET option
|
|
>option unset unset by setting nounset
|
|
>option unset reset
|
|
>
|
|
?fn: foo: parameter not set
|
|
|
|
# This really just tests if XTRACE is egregiously broken.
|
|
# To test it properly would need a full set of its own.
|
|
fn() { print message; }
|
|
setopt xtrace
|
|
fn
|
|
unsetopt xtrace
|
|
fn
|
|
0:XTRACE option
|
|
>message
|
|
>message
|
|
?+(eval):3> fn
|
|
?+fn:0> print message
|
|
?+(eval):4> unsetopt xtrace
|