mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
-o posix: disable '[ -t ]' == '[ -t 1 ]' hack
On ksh93, 'test -t' is equivalent to 'test -t 1' (and of course
"[ -t ]" is equivalent to "[ -t 1 ]").
This is purely for compatibility with ancient Bourne shell
breakage. No other shell supports this. ksh93 should probably keep
it for backwards compatibility, but it should definitely be
disabled in POSIX mode as it is a violation of the standard; 'test
-t' is an instance of 'test "$string"', which tests if the string
is empty, so it should test if the string '-t' is empty (quod non).
This also replaces the fix for 'test -t 1' in a command
substitution with a better one that avoids forking (re: cafe33f0
).
src/cmd/ksh93/sh/parse.c:
- qscan(): If the posix option is active, disable the parser-based
hack that converts a simple "[ -t ]" to "[ -t 1 ]".
src/cmd/ksh93/bltins/test.c:
- e3(): If the posix option is active, disable the part of the
compatibility hack that was used for compound expressions
that end in '-t', e.g. "[ -t 2 -o -t ]".
- test_unop(): Remove the forking fix for "[ -t 1 ]".
src/cmd/ksh93/edit/edit.c:
- tty_check(): This function is used by "[ -t 1 ]" and in other
contexts as well, so a fix here is more comprehensive. Forking
here would cause a segfault, but we don't actually need to. This
adds a fix that simply returns false if we're in a virtual
subshell that is also a command substitution. Since command
substitutions always fork upon redirecting standard output within
them (making them no longer virtual), it is safe to do this.
src/cmd/ksh93/tests/bracket.sh
- Add comprehensive regression tests for test/[/[[ -t variants in
command substitutions, in simple and compound expressions, with
and without redirecting stdout to /dev/tty within the comsub.
- Add tests verifying that -o posix disables the old hack.
- Tweak other tests, including one that globally disabled xtrace.
This commit is contained in:
parent
9077fcc3a4
commit
55f0f8ce52
6 changed files with 75 additions and 25 deletions
|
@ -202,11 +202,12 @@ exec 4>&-
|
|||
if [[ 011 -ne 11 ]]
|
||||
then err_exit "leading zeros in arithmetic compares not ignored"
|
||||
fi
|
||||
{
|
||||
set -x
|
||||
[[ foo > bar ]]
|
||||
} 2> /dev/null || { set +x; err_exit "foo<bar with -x enabled" ;}
|
||||
set +x
|
||||
(
|
||||
{
|
||||
set -x
|
||||
[[ foo > bar ]]
|
||||
} 2> /dev/null
|
||||
) || err_exit "foo<bar with -x enabled"
|
||||
(
|
||||
eval "[[ (a) ]]"
|
||||
) 2> /dev/null || err_exit "[[ (a) ]] not working"
|
||||
|
@ -367,24 +368,58 @@ test ! ! '' 2> /dev/null && err_exit 'test ! ! "" should return non-zero'
|
|||
|
||||
# This is the simple case that doesn't do any redirection of stdout within the command
|
||||
# substitution. Thus the [ -t 1 ] test should be false.
|
||||
var=$(echo begin; { [ -t 1 ] || test -t 1 || [[ -t 1 ]]; } && echo -t 1 is true; echo end)
|
||||
[[ $var == $'begin\nend' ]] || err_exit "test -t 1 in comsub fails"
|
||||
expect=$'begin\nend'
|
||||
actual=$(echo begin; [ -t 1 ] || test -t 1 || [[ -t 1 ]] && echo -t 1 is true; echo end)
|
||||
[[ $actual == "$expect" ]] || err_exit 'test -t 1 in comsub fails' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
actual=$(echo begin; [ -n X -a -t 1 ] || test -n X -a -t 1 || [[ -n X && -t 1 ]] && echo -t 1 is true; echo end)
|
||||
[[ $actual == "$expect" ]] || err_exit 'test -t 1 in comsub fails (compound expression)' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
# Same for the ancient compatibility hack for 'test -t' with no arguments.
|
||||
actual=$(echo begin; [ -t ] || test -t && echo -t is true; echo end)
|
||||
[[ $actual == "$expect" ]] || err_exit 'test -t in comsub fails' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
actual=$(echo begin; [ -n X -a -t ] || test -n X -a -t && echo -t is true; echo end)
|
||||
[[ $actual == "$expect" ]] || err_exit 'test -t in comsub fails (compound expression)' \
|
||||
"(expected $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# This is the more complex case that does redirect stdout within the command substitution to the
|
||||
# actual tty. Thus the [ -t 1 ] test should be true.
|
||||
var=$(echo begin; exec >/dev/tty; [ -t 1 ] && test -t 1 && [[ -t 1 ]]) \
|
||||
&& [[ $var == $'begin' ]] \
|
||||
|| err_exit "test -t 1 in comsub with exec >/dev/tty fails"
|
||||
actual=$(echo begin; exec >/dev/tty; [ -t 1 ] && test -t 1 && [[ -t 1 ]]) \
|
||||
|| err_exit 'test -t 1 in comsub with exec >/dev/tty fails'
|
||||
actual=$(echo begin; exec >/dev/tty; [ -n X -a -t 1 ] && test -n X -a -t 1 && [[ -n X && -t 1 ]]) \
|
||||
|| err_exit 'test -t 1 in comsub with exec >/dev/tty fails (compound expression)'
|
||||
# Same for the ancient compatibility hack for 'test -t' with no arguments.
|
||||
actual=$(echo begin; exec >/dev/tty; [ -t ] && test -t) \
|
||||
|| err_exit 'test -t in comsub with exec >/dev/tty fails'
|
||||
actual=$(echo begin; exec >/dev/tty; [ -n X -a -t ] && test -n X -a -t) \
|
||||
|| err_exit 'test -t in comsub with exec >/dev/tty fails (compound expression)'
|
||||
|
||||
# The POSIX mode should disable the ancient 'test -t' compatibility hack.
|
||||
if [[ -o ?posix ]]
|
||||
then # need 'eval' in first test, as it's a parser hack, and ksh normally parses ahead of execution
|
||||
(set -o posix; eval '[ -t ] && test -t') >/dev/null \
|
||||
|| err_exit "posix mode fails to disable 'test -t' compat hack"
|
||||
# the compound command variant of the hack is in the 'test' builtin itself; no 'eval' needed
|
||||
expect=$'*: argument expected\n*: argument expected'
|
||||
actual=$(set -o posix; [ -n X -a -t ] 2>&1; test -n X -a -t 2>&1)
|
||||
[[ $actual == $expect ]] || err_exit "posix mode fails to disable 'test -t' compat hack (compound expression)" \
|
||||
"(expected output matching $(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
fi
|
||||
|
||||
# ======
|
||||
# POSIX specifies that on error, test builtin should always return status > 1
|
||||
test 123 -eq 123x 2>/dev/null
|
||||
[[ $? -ge 2 ]] || err_exit 'test builtin should return value greater than 1 on error'
|
||||
expect=$': test: 123x: arithmetic syntax error\nExit status: 2'
|
||||
actual=$(test 123 -eq 123x 2>&1; echo "Exit status: $?")
|
||||
[[ $actual == *"$expect" ]] || err_exit 'test builtin does not error out with status 2' \
|
||||
"(expected *$(printf %q "$expect"), got $(printf %q "$actual"))"
|
||||
|
||||
# ======
|
||||
# The '=~' operator should work with curly brackets
|
||||
$SHELL -c '[[ AATAAT =~ (AAT){2} ]]' || err_exit '[[ AATAAT =~ (AAT){2} ]] does not match'
|
||||
$SHELL -c '[[ AATAATCCCAATAAT =~ (AAT){2}CCC(AAT){2} ]]' || err_exit '[[ AATAATCCCAATAAT =~ (AAT){2}CCC(AAT){2} ]] does not match'
|
||||
error=$(set +x; "$SHELL" -c '[[ AATAAT =~ (AAT){2} ]]' 2>&1) \
|
||||
|| err_exit "[[ AATAAT =~ (AAT){2} ]] does not match${error:+ (got $(printf %q "$error"))}"
|
||||
error=$(set +x; "$SHELL" -c '[[ AATAATCCCAATAAT =~ (AAT){2}CCC(AAT){2} ]]' 2>&1) \
|
||||
|| err_exit "[[ AATAATCCCAATAAT =~ (AAT){2}CCC(AAT){2} ]] does not match${error:+ (got $(printf %q "$error"))}"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue