mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-21 12:57:58 +02:00
fix cosmetic error when printing if commands containing here-documents in the body; compiling -DSTRICT_POSIX now forces posix-mode shells to expand redirections before assignment statements preceding simple commands
This commit is contained in:
@@ -12721,3 +12721,39 @@ subst.c,subst.h
|
||||
- expand_words: call expand_assignment_statements instead of
|
||||
do_assignment_statements, remove some duplicate code
|
||||
|
||||
2/25
|
||||
----
|
||||
print_cmd.c
|
||||
- print_if_command: if we have just printed the `action' command,
|
||||
and it ends with a here-document, fix indentation amount
|
||||
Report and fix from Weixie Cui <523516579@qq.com>
|
||||
|
||||
2/27
|
||||
----
|
||||
subst.c
|
||||
- WEXP_DEFERVARS: new word expansion flag, means to defer assignment
|
||||
statements until after other word expansions and redirections
|
||||
- WEXP_POSIX: new flag set for expand_word_list_internal, means to
|
||||
separate out the assignment statements but leave them in
|
||||
SUBST_ASSIGN_VARLIST
|
||||
- if STRICT_POSIX is defined, expand_words calls expand_word_list_internal
|
||||
with WEXP_POSIX when in posix mode
|
||||
- expand_word_list_internal: only call expand_assignment_statements if
|
||||
WEXP_DEFERVARS is not set in EFLAGS. It can only be set if the shell
|
||||
is compiled -DSTRICT_POSIX and in posix mode
|
||||
|
||||
execute_cmd.c
|
||||
- execute_null_command: if compiled -DSTRICT_POSIX and in posix mode,
|
||||
expand assignment statements after performing redirections and only
|
||||
if the redirections complete without errors
|
||||
- execute_subshell_builtin_or_function,execute_builtin_or_function:
|
||||
if compiled -DSTRICT_POSIX and in posix mode, expand assignment
|
||||
statements after performing redirections and only if the
|
||||
redirections complete without errors
|
||||
- execute_simple_command: if compiled -DSTRICT_POSIX and in posix mode,
|
||||
expand assignment statements after performing redirections and only
|
||||
if the redirections complete without errors, and defer environment
|
||||
creation until after calling expand_assignment_statements()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -533,6 +533,7 @@ m4/bison.m4 f
|
||||
m4/c-bool.m4 f
|
||||
m4/codeset.m4 f
|
||||
m4/d-type.m4 f
|
||||
m4/environ.m4 f
|
||||
m4/extern-inline.m4 f
|
||||
m4/fcntl-o.m4 f
|
||||
m4/flexmember.m4 f
|
||||
|
||||
@@ -387,7 +387,13 @@ default even when in POSIX mode. Specifically:
|
||||
entries if ‘FCEDIT’ is unset, rather than defaulting directly to
|
||||
‘ed’. ‘fc’ uses ‘ed’ if ‘EDITOR’ is unset.
|
||||
|
||||
3. As noted above, Bash requires the ‘xpg_echo’ option to be enabled
|
||||
3. Bash does not perform redirections before expanding variable
|
||||
assignments preceding a simple command; it does not allow the
|
||||
redirections access to the results of the variable assignments, but
|
||||
any side effects of expanding the redirections take place first.
|
||||
If compiled in strict posix mode, Bash performs redirections first.
|
||||
|
||||
4. As noted above, Bash requires the ‘xpg_echo’ option to be enabled
|
||||
for the ‘echo’ builtin to be fully conformant.
|
||||
|
||||
Bash can be configured to be POSIX-conformant by default, by specifying
|
||||
|
||||
@@ -278,6 +278,58 @@ assoc_subrange (HASH_TABLE *hash, arrayind_t start, arrayind_t nelem, int starsu
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string whose elements are the members of array H beginning at
|
||||
* the element with key START and ending with key END.
|
||||
* Order is non-deterministic and determined by walking the hash table
|
||||
* from beginning to end (assoc_to_word_list()).
|
||||
* If START isn't found, this starts at the beginning of the list created
|
||||
* from the hash table.
|
||||
* If END isn't found, this returns START.
|
||||
* If neither START nor END is found, this returns the first entry in the list.
|
||||
* These semantics are compatible with the ksh93 ${assoc[k1..k2]} expansion.
|
||||
*/
|
||||
char *
|
||||
assoc_subslice (HASH_TABLE *hash, char *start, char *end, int starsub, int quoted, int pflags)
|
||||
{
|
||||
WORD_LIST *l, *save, *h, *t;
|
||||
int i, j;
|
||||
char *ret;
|
||||
|
||||
if (assoc_empty (hash))
|
||||
return ((char *)NULL);
|
||||
|
||||
save = l = assoc_to_word_list (hash);
|
||||
if (save == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
for (h = l; h; h = h->next)
|
||||
if (STREQ (start, h->word->word))
|
||||
break;
|
||||
|
||||
if (h == 0) /* XXX could return NULL here */
|
||||
h = l;
|
||||
|
||||
for (t = h; t; t = t->next)
|
||||
if (STREQ (end, t->word->word))
|
||||
break;
|
||||
|
||||
/* XXX could leave it set to the last element by leaving t = 0 and not
|
||||
messing around with t->next below */
|
||||
if (t == 0)
|
||||
t = h;
|
||||
|
||||
l = t->next;
|
||||
t->next = (WORD_LIST *)NULL;
|
||||
|
||||
ret = string_list_pos_params (starsub ? '*' : '@', h, quoted, pflags);
|
||||
|
||||
t->next = l;
|
||||
|
||||
dispose_words (save);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Substitute REP for each match of PAT in each element of hash table H,
|
||||
qualified by FLAGS to say what kind of quoting to do. */
|
||||
char *
|
||||
|
||||
@@ -46,6 +46,7 @@ extern void assoc_remove (HASH_TABLE *, const char *);
|
||||
extern char *assoc_reference (HASH_TABLE *, const char *);
|
||||
|
||||
extern char *assoc_subrange (HASH_TABLE *, arrayind_t, arrayind_t, int, int, int);
|
||||
extern char *assoc_subslice (HASH_TABLE *, char *, char *, int, int, int);
|
||||
extern char *assoc_patsub (HASH_TABLE *, char *, char *, int);
|
||||
extern char *assoc_modcase (HASH_TABLE *, char *, int, int);
|
||||
|
||||
|
||||
+1
-1
@@ -1052,7 +1052,7 @@ builtin_arrayref_flags (WORD_DESC *w, int baseflags)
|
||||
|
||||
# if 0
|
||||
/* This is a little sketchier but handles quoted arguments. */
|
||||
if (array_expand_once && (t = strchr (w->word, '[')) && t[strlen(t) - 1] == ']')
|
||||
if (array_expand_once && (t = strchr (w->word, '[')) && t[strlen(t) - 1] == ']')
|
||||
vflags |= VA_ONEWORD|VA_NOEXPAND;
|
||||
# endif
|
||||
|
||||
|
||||
+4
-4
@@ -29,8 +29,8 @@ Read and execute commands from FILENAME in the current shell. If the
|
||||
-p option is supplied, the PATH argument is treated as a colon-
|
||||
separated list of directories to search for FILENAME. If -p is not
|
||||
supplied, and the sourcepath shell option is enabled, 'source' searches
|
||||
$PATH to find FILENAME. If any ARGUMENTS are supplied, they become the
|
||||
positional parameters when FILENAME is executed.
|
||||
the directories in $PATH to find FILENAME. If any ARGUMENTS are supplied,
|
||||
they become the positional parameters when FILENAME is executed.
|
||||
|
||||
Exit Status:
|
||||
Returns the status of the last command executed in FILENAME; fails if
|
||||
@@ -47,8 +47,8 @@ Read and execute commands from FILENAME in the current shell. If the
|
||||
-p option is supplied, the PATH argument is treated as a colon-
|
||||
separated list of directories to search for FILENAME. If -p is not
|
||||
supplied, and the sourcepath shell option is enabled, '.' searches
|
||||
$PATH to find FILENAME. If any ARGUMENTS are supplied, they become the
|
||||
positional parameters when FILENAME is executed.
|
||||
the directories in $PATH to find FILENAME. If any ARGUMENTS are supplied,
|
||||
they become the positional parameters when FILENAME is executed.
|
||||
|
||||
Exit Status:
|
||||
Returns the status of the last command executed in FILENAME; fails if
|
||||
|
||||
@@ -7116,6 +7116,16 @@ fi
|
||||
|
||||
|
||||
|
||||
# environ.m4
|
||||
# serial 8
|
||||
|
||||
|
||||
|
||||
# Check if a variable is properly declared.
|
||||
# gt_CHECK_VAR_DECL(includes,variable)
|
||||
|
||||
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
|
||||
printf %s "checking for an ANSI C-conforming const... " >&6; }
|
||||
if test ${ac_cv_c_const+y}
|
||||
@@ -9415,8 +9425,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
LIBS=$save_LIBS
|
||||
test $gl_pthread_api = yes && break
|
||||
done
|
||||
echo "$as_me:9418: gl_pthread_api=$gl_pthread_api" >&5
|
||||
echo "$as_me:9419: LIBPTHREAD=$LIBPTHREAD" >&5
|
||||
echo "$as_me:9428: gl_pthread_api=$gl_pthread_api" >&5
|
||||
echo "$as_me:9429: LIBPTHREAD=$LIBPTHREAD" >&5
|
||||
|
||||
gl_pthread_in_glibc=no
|
||||
# On Linux with glibc >= 2.34, libc contains the fully functional
|
||||
@@ -9442,7 +9452,7 @@ rm -rf conftest*
|
||||
|
||||
;;
|
||||
esac
|
||||
echo "$as_me:9445: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
|
||||
echo "$as_me:9455: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
|
||||
|
||||
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
|
||||
# since it is defined as a macro on OSF/1.)
|
||||
@@ -9620,7 +9630,7 @@ fi
|
||||
|
||||
fi
|
||||
fi
|
||||
echo "$as_me:9623: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
|
||||
echo "$as_me:9633: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
|
||||
printf %s "checking whether POSIX threads API is available... " >&6; }
|
||||
@@ -9867,8 +9877,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
LIBS=$save_LIBS
|
||||
test $gl_pthread_api = yes && break
|
||||
done
|
||||
echo "$as_me:9870: gl_pthread_api=$gl_pthread_api" >&5
|
||||
echo "$as_me:9871: LIBPTHREAD=$LIBPTHREAD" >&5
|
||||
echo "$as_me:9880: gl_pthread_api=$gl_pthread_api" >&5
|
||||
echo "$as_me:9881: LIBPTHREAD=$LIBPTHREAD" >&5
|
||||
|
||||
gl_pthread_in_glibc=no
|
||||
# On Linux with glibc >= 2.34, libc contains the fully functional
|
||||
@@ -9894,7 +9904,7 @@ rm -rf conftest*
|
||||
|
||||
;;
|
||||
esac
|
||||
echo "$as_me:9897: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
|
||||
echo "$as_me:9907: gl_pthread_in_glibc=$gl_pthread_in_glibc" >&5
|
||||
|
||||
# Test for libpthread by looking for pthread_kill. (Not pthread_self,
|
||||
# since it is defined as a macro on OSF/1.)
|
||||
@@ -10072,7 +10082,7 @@ fi
|
||||
|
||||
fi
|
||||
fi
|
||||
echo "$as_me:10075: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
|
||||
echo "$as_me:10085: LIBPMULTITHREAD=$LIBPMULTITHREAD" >&5
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX threads API is available" >&5
|
||||
printf %s "checking whether POSIX threads API is available... " >&6; }
|
||||
|
||||
+3
-1
@@ -5,7 +5,7 @@ dnl report bugs to chet.ramey@case.edu
|
||||
dnl
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
# Copyright (C) 1987-2025 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1987-2026 Free Software Foundation, Inc.
|
||||
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -783,6 +783,8 @@ m4_include([m4/host-cpu-c-abi.m4])
|
||||
m4_include([m4/c-bool.m4])
|
||||
m4_include([m4/d-type.m4])
|
||||
|
||||
m4_include([m4/environ.m4])
|
||||
|
||||
dnl C compiler characteristics
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
|
||||
+145
-138
@@ -1,9 +1,9 @@
|
||||
This is bash.info, produced by makeinfo version 7.2 from bashref.texi.
|
||||
|
||||
This text is a brief description of the features that are present in the
|
||||
Bash shell (version 5.3, 14 January 2026).
|
||||
Bash shell (version 5.3, 27 February 2026).
|
||||
|
||||
This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash
|
||||
This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash
|
||||
Reference Manual’, for ‘Bash’, Version 5.3.
|
||||
|
||||
Copyright © 1988-2026 Free Software Foundation, Inc.
|
||||
@@ -26,10 +26,10 @@ Bash Features
|
||||
*************
|
||||
|
||||
This text is a brief description of the features that are present in the
|
||||
Bash shell (version 5.3, 14 January 2026). The Bash home page is
|
||||
Bash shell (version 5.3, 27 February 2026). The Bash home page is
|
||||
<http://www.gnu.org/software/bash/>.
|
||||
|
||||
This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash
|
||||
This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash
|
||||
Reference Manual’, for ‘Bash’, Version 5.3.
|
||||
|
||||
Bash contains features that appear in other popular shells, and some
|
||||
@@ -7774,7 +7774,8 @@ startup files.
|
||||
builtins.
|
||||
|
||||
12. Tilde expansion is only performed on assignments preceding a
|
||||
command name, rather than on all assignment statements on the line.
|
||||
command name, rather than on all assignment statements on the line,
|
||||
unless the command is a declaration command.
|
||||
|
||||
13. While variable indirection is available, it may not be applied to
|
||||
the ‘#’ and ‘?’ special parameters.
|
||||
@@ -8062,7 +8063,13 @@ default even when in POSIX mode. Specifically:
|
||||
entries if ‘FCEDIT’ is unset, rather than defaulting directly to
|
||||
‘ed’. ‘fc’ uses ‘ed’ if ‘EDITOR’ is unset.
|
||||
|
||||
3. As noted above, Bash requires the ‘xpg_echo’ option to be enabled
|
||||
3. Bash does not perform redirections before expanding variable
|
||||
assignments preceding a simple command; it does not allow the
|
||||
redirections access to the results of the variable assignments, but
|
||||
any side effects of expanding the redirections take place first.
|
||||
If compiled in strict posix mode, Bash performs redirections first.
|
||||
|
||||
4. As noted above, Bash requires the ‘xpg_echo’ option to be enabled
|
||||
for the ‘echo’ builtin to be fully conformant.
|
||||
|
||||
Bash can be configured to be POSIX-conformant by default, by
|
||||
@@ -13728,138 +13735,138 @@ D.5 Concept Index
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top899
|
||||
Node: Introduction2838
|
||||
Node: What is Bash?3051
|
||||
Node: What is a shell?4184
|
||||
Node: Definitions6794
|
||||
Node: Basic Shell Features10121
|
||||
Node: Shell Syntax11345
|
||||
Node: Shell Operation12372
|
||||
Node: Quoting13663
|
||||
Node: Escape Character15001
|
||||
Node: Single Quotes15536
|
||||
Node: Double Quotes15885
|
||||
Node: ANSI-C Quoting17230
|
||||
Node: Locale Translation18624
|
||||
Node: Creating Internationalized Scripts20027
|
||||
Node: Comments24225
|
||||
Node: Shell Commands24992
|
||||
Node: Reserved Words25931
|
||||
Node: Simple Commands27074
|
||||
Node: Pipelines27736
|
||||
Node: Lists30992
|
||||
Node: Compound Commands32941
|
||||
Node: Looping Constructs33950
|
||||
Node: Conditional Constructs36499
|
||||
Node: Command Grouping51636
|
||||
Node: Coprocesses53128
|
||||
Node: GNU Parallel55814
|
||||
Node: Shell Functions56732
|
||||
Node: Shell Parameters65180
|
||||
Node: Positional Parameters70081
|
||||
Node: Special Parameters71171
|
||||
Node: Shell Expansions74632
|
||||
Node: Brace Expansion76821
|
||||
Node: Tilde Expansion80157
|
||||
Node: Shell Parameter Expansion83112
|
||||
Node: Command Substitution103759
|
||||
Node: Arithmetic Expansion107610
|
||||
Node: Process Substitution108786
|
||||
Node: Word Splitting109894
|
||||
Node: Filename Expansion112338
|
||||
Node: Pattern Matching115562
|
||||
Node: Quote Removal121328
|
||||
Node: Redirections121632
|
||||
Node: Executing Commands131888
|
||||
Node: Simple Command Expansion132555
|
||||
Node: Command Search and Execution134663
|
||||
Node: Command Execution Environment137107
|
||||
Node: Environment140633
|
||||
Node: Exit Status142536
|
||||
Node: Signals144595
|
||||
Node: Shell Scripts149543
|
||||
Node: Shell Builtin Commands152841
|
||||
Node: Bourne Shell Builtins155182
|
||||
Node: Bash Builtins181901
|
||||
Node: Modifying Shell Behavior219637
|
||||
Node: The Set Builtin219979
|
||||
Node: The Shopt Builtin231973
|
||||
Node: Special Builtins249026
|
||||
Node: Shell Variables250015
|
||||
Node: Bourne Shell Variables250449
|
||||
Node: Bash Variables252957
|
||||
Node: Bash Features292241
|
||||
Node: Invoking Bash293255
|
||||
Node: Bash Startup Files299839
|
||||
Node: Interactive Shells305081
|
||||
Node: What is an Interactive Shell?305489
|
||||
Node: Is this Shell Interactive?306151
|
||||
Node: Interactive Shell Behavior306975
|
||||
Node: Bash Conditional Expressions310736
|
||||
Node: Shell Arithmetic316153
|
||||
Node: Aliases319480
|
||||
Node: Arrays322614
|
||||
Node: The Directory Stack330317
|
||||
Node: Directory Stack Builtins331114
|
||||
Node: Controlling the Prompt335559
|
||||
Node: The Restricted Shell338443
|
||||
Node: Bash POSIX Mode341536
|
||||
Node: Shell Compatibility Mode360952
|
||||
Node: Job Control369959
|
||||
Node: Job Control Basics370416
|
||||
Node: Job Control Builtins376784
|
||||
Node: Job Control Variables383572
|
||||
Node: Command Line Editing384803
|
||||
Node: Introduction and Notation386506
|
||||
Node: Readline Interaction388858
|
||||
Node: Readline Bare Essentials390046
|
||||
Node: Readline Movement Commands391854
|
||||
Node: Readline Killing Commands392850
|
||||
Node: Readline Arguments394873
|
||||
Node: Searching395963
|
||||
Node: Readline Init File398206
|
||||
Node: Readline Init File Syntax399509
|
||||
Node: Conditional Init Constructs426460
|
||||
Node: Sample Init File430845
|
||||
Node: Bindable Readline Commands433965
|
||||
Node: Commands For Moving435503
|
||||
Node: Commands For History437967
|
||||
Node: Commands For Text443358
|
||||
Node: Commands For Killing447483
|
||||
Node: Numeric Arguments450271
|
||||
Node: Commands For Completion451423
|
||||
Node: Keyboard Macros457119
|
||||
Node: Miscellaneous Commands457820
|
||||
Node: Readline vi Mode465363
|
||||
Node: Programmable Completion466340
|
||||
Node: Programmable Completion Builtins476076
|
||||
Node: A Programmable Completion Example487813
|
||||
Node: Using History Interactively493158
|
||||
Node: Bash History Facilities493839
|
||||
Node: Bash History Builtins497574
|
||||
Node: History Interaction505169
|
||||
Node: Event Designators510119
|
||||
Node: Word Designators511697
|
||||
Node: Modifiers514089
|
||||
Node: Installing Bash516026
|
||||
Node: Basic Installation517142
|
||||
Node: Compilers and Options521018
|
||||
Node: Compiling For Multiple Architectures521768
|
||||
Node: Installation Names523521
|
||||
Node: Specifying the System Type525755
|
||||
Node: Sharing Defaults526501
|
||||
Node: Operation Controls527215
|
||||
Node: Optional Features528234
|
||||
Node: Reporting Bugs540957
|
||||
Node: Major Differences From The Bourne Shell542314
|
||||
Node: GNU Free Documentation License563741
|
||||
Node: Indexes588918
|
||||
Node: Builtin Index589369
|
||||
Node: Reserved Word Index596467
|
||||
Node: Variable Index598912
|
||||
Node: Function Index616325
|
||||
Node: Concept Index630458
|
||||
Node: Top901
|
||||
Node: Introduction2842
|
||||
Node: What is Bash?3055
|
||||
Node: What is a shell?4188
|
||||
Node: Definitions6798
|
||||
Node: Basic Shell Features10125
|
||||
Node: Shell Syntax11349
|
||||
Node: Shell Operation12376
|
||||
Node: Quoting13667
|
||||
Node: Escape Character15005
|
||||
Node: Single Quotes15540
|
||||
Node: Double Quotes15889
|
||||
Node: ANSI-C Quoting17234
|
||||
Node: Locale Translation18628
|
||||
Node: Creating Internationalized Scripts20031
|
||||
Node: Comments24229
|
||||
Node: Shell Commands24996
|
||||
Node: Reserved Words25935
|
||||
Node: Simple Commands27078
|
||||
Node: Pipelines27740
|
||||
Node: Lists30996
|
||||
Node: Compound Commands32945
|
||||
Node: Looping Constructs33954
|
||||
Node: Conditional Constructs36503
|
||||
Node: Command Grouping51640
|
||||
Node: Coprocesses53132
|
||||
Node: GNU Parallel55818
|
||||
Node: Shell Functions56736
|
||||
Node: Shell Parameters65184
|
||||
Node: Positional Parameters70085
|
||||
Node: Special Parameters71175
|
||||
Node: Shell Expansions74636
|
||||
Node: Brace Expansion76825
|
||||
Node: Tilde Expansion80161
|
||||
Node: Shell Parameter Expansion83116
|
||||
Node: Command Substitution103763
|
||||
Node: Arithmetic Expansion107614
|
||||
Node: Process Substitution108790
|
||||
Node: Word Splitting109898
|
||||
Node: Filename Expansion112342
|
||||
Node: Pattern Matching115566
|
||||
Node: Quote Removal121332
|
||||
Node: Redirections121636
|
||||
Node: Executing Commands131892
|
||||
Node: Simple Command Expansion132559
|
||||
Node: Command Search and Execution134667
|
||||
Node: Command Execution Environment137111
|
||||
Node: Environment140637
|
||||
Node: Exit Status142540
|
||||
Node: Signals144599
|
||||
Node: Shell Scripts149547
|
||||
Node: Shell Builtin Commands152845
|
||||
Node: Bourne Shell Builtins155186
|
||||
Node: Bash Builtins181905
|
||||
Node: Modifying Shell Behavior219641
|
||||
Node: The Set Builtin219983
|
||||
Node: The Shopt Builtin231977
|
||||
Node: Special Builtins249030
|
||||
Node: Shell Variables250019
|
||||
Node: Bourne Shell Variables250453
|
||||
Node: Bash Variables252961
|
||||
Node: Bash Features292245
|
||||
Node: Invoking Bash293259
|
||||
Node: Bash Startup Files299843
|
||||
Node: Interactive Shells305085
|
||||
Node: What is an Interactive Shell?305493
|
||||
Node: Is this Shell Interactive?306155
|
||||
Node: Interactive Shell Behavior306979
|
||||
Node: Bash Conditional Expressions310740
|
||||
Node: Shell Arithmetic316157
|
||||
Node: Aliases319484
|
||||
Node: Arrays322618
|
||||
Node: The Directory Stack330321
|
||||
Node: Directory Stack Builtins331118
|
||||
Node: Controlling the Prompt335563
|
||||
Node: The Restricted Shell338447
|
||||
Node: Bash POSIX Mode341540
|
||||
Node: Shell Compatibility Mode361356
|
||||
Node: Job Control370363
|
||||
Node: Job Control Basics370820
|
||||
Node: Job Control Builtins377188
|
||||
Node: Job Control Variables383976
|
||||
Node: Command Line Editing385207
|
||||
Node: Introduction and Notation386910
|
||||
Node: Readline Interaction389262
|
||||
Node: Readline Bare Essentials390450
|
||||
Node: Readline Movement Commands392258
|
||||
Node: Readline Killing Commands393254
|
||||
Node: Readline Arguments395277
|
||||
Node: Searching396367
|
||||
Node: Readline Init File398610
|
||||
Node: Readline Init File Syntax399913
|
||||
Node: Conditional Init Constructs426864
|
||||
Node: Sample Init File431249
|
||||
Node: Bindable Readline Commands434369
|
||||
Node: Commands For Moving435907
|
||||
Node: Commands For History438371
|
||||
Node: Commands For Text443762
|
||||
Node: Commands For Killing447887
|
||||
Node: Numeric Arguments450675
|
||||
Node: Commands For Completion451827
|
||||
Node: Keyboard Macros457523
|
||||
Node: Miscellaneous Commands458224
|
||||
Node: Readline vi Mode465767
|
||||
Node: Programmable Completion466744
|
||||
Node: Programmable Completion Builtins476480
|
||||
Node: A Programmable Completion Example488217
|
||||
Node: Using History Interactively493562
|
||||
Node: Bash History Facilities494243
|
||||
Node: Bash History Builtins497978
|
||||
Node: History Interaction505573
|
||||
Node: Event Designators510523
|
||||
Node: Word Designators512101
|
||||
Node: Modifiers514493
|
||||
Node: Installing Bash516430
|
||||
Node: Basic Installation517546
|
||||
Node: Compilers and Options521422
|
||||
Node: Compiling For Multiple Architectures522172
|
||||
Node: Installation Names523925
|
||||
Node: Specifying the System Type526159
|
||||
Node: Sharing Defaults526905
|
||||
Node: Operation Controls527619
|
||||
Node: Optional Features528638
|
||||
Node: Reporting Bugs541361
|
||||
Node: Major Differences From The Bourne Shell542718
|
||||
Node: GNU Free Documentation License564145
|
||||
Node: Indexes589322
|
||||
Node: Builtin Index589773
|
||||
Node: Reserved Word Index596871
|
||||
Node: Variable Index599316
|
||||
Node: Function Index616729
|
||||
Node: Concept Index630862
|
||||
|
||||
End Tag Table
|
||||
|
||||
|
||||
+145
-138
@@ -2,9 +2,9 @@ This is bashref.info, produced by makeinfo version 7.2 from
|
||||
bashref.texi.
|
||||
|
||||
This text is a brief description of the features that are present in the
|
||||
Bash shell (version 5.3, 14 January 2026).
|
||||
Bash shell (version 5.3, 27 February 2026).
|
||||
|
||||
This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash
|
||||
This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash
|
||||
Reference Manual’, for ‘Bash’, Version 5.3.
|
||||
|
||||
Copyright © 1988-2026 Free Software Foundation, Inc.
|
||||
@@ -27,10 +27,10 @@ Bash Features
|
||||
*************
|
||||
|
||||
This text is a brief description of the features that are present in the
|
||||
Bash shell (version 5.3, 14 January 2026). The Bash home page is
|
||||
Bash shell (version 5.3, 27 February 2026). The Bash home page is
|
||||
<http://www.gnu.org/software/bash/>.
|
||||
|
||||
This is Edition 5.3, last updated 14 January 2026, of ‘The GNU Bash
|
||||
This is Edition 5.3, last updated 27 February 2026, of ‘The GNU Bash
|
||||
Reference Manual’, for ‘Bash’, Version 5.3.
|
||||
|
||||
Bash contains features that appear in other popular shells, and some
|
||||
@@ -7775,7 +7775,8 @@ startup files.
|
||||
builtins.
|
||||
|
||||
12. Tilde expansion is only performed on assignments preceding a
|
||||
command name, rather than on all assignment statements on the line.
|
||||
command name, rather than on all assignment statements on the line,
|
||||
unless the command is a declaration command.
|
||||
|
||||
13. While variable indirection is available, it may not be applied to
|
||||
the ‘#’ and ‘?’ special parameters.
|
||||
@@ -8063,7 +8064,13 @@ default even when in POSIX mode. Specifically:
|
||||
entries if ‘FCEDIT’ is unset, rather than defaulting directly to
|
||||
‘ed’. ‘fc’ uses ‘ed’ if ‘EDITOR’ is unset.
|
||||
|
||||
3. As noted above, Bash requires the ‘xpg_echo’ option to be enabled
|
||||
3. Bash does not perform redirections before expanding variable
|
||||
assignments preceding a simple command; it does not allow the
|
||||
redirections access to the results of the variable assignments, but
|
||||
any side effects of expanding the redirections take place first.
|
||||
If compiled in strict posix mode, Bash performs redirections first.
|
||||
|
||||
4. As noted above, Bash requires the ‘xpg_echo’ option to be enabled
|
||||
for the ‘echo’ builtin to be fully conformant.
|
||||
|
||||
Bash can be configured to be POSIX-conformant by default, by
|
||||
@@ -13729,138 +13736,138 @@ D.5 Concept Index
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top902
|
||||
Node: Introduction2844
|
||||
Node: What is Bash?3060
|
||||
Node: What is a shell?4196
|
||||
Node: Definitions6809
|
||||
Node: Basic Shell Features10139
|
||||
Node: Shell Syntax11366
|
||||
Node: Shell Operation12396
|
||||
Node: Quoting13690
|
||||
Node: Escape Character15031
|
||||
Node: Single Quotes15569
|
||||
Node: Double Quotes15921
|
||||
Node: ANSI-C Quoting17269
|
||||
Node: Locale Translation18666
|
||||
Node: Creating Internationalized Scripts20072
|
||||
Node: Comments24273
|
||||
Node: Shell Commands25043
|
||||
Node: Reserved Words25985
|
||||
Node: Simple Commands27131
|
||||
Node: Pipelines27796
|
||||
Node: Lists31055
|
||||
Node: Compound Commands33007
|
||||
Node: Looping Constructs34019
|
||||
Node: Conditional Constructs36571
|
||||
Node: Command Grouping51711
|
||||
Node: Coprocesses53206
|
||||
Node: GNU Parallel55895
|
||||
Node: Shell Functions56816
|
||||
Node: Shell Parameters65267
|
||||
Node: Positional Parameters70171
|
||||
Node: Special Parameters71264
|
||||
Node: Shell Expansions74728
|
||||
Node: Brace Expansion76920
|
||||
Node: Tilde Expansion80259
|
||||
Node: Shell Parameter Expansion83217
|
||||
Node: Command Substitution103867
|
||||
Node: Arithmetic Expansion107721
|
||||
Node: Process Substitution108900
|
||||
Node: Word Splitting110011
|
||||
Node: Filename Expansion112458
|
||||
Node: Pattern Matching115685
|
||||
Node: Quote Removal121454
|
||||
Node: Redirections121761
|
||||
Node: Executing Commands132020
|
||||
Node: Simple Command Expansion132690
|
||||
Node: Command Search and Execution134801
|
||||
Node: Command Execution Environment137248
|
||||
Node: Environment140777
|
||||
Node: Exit Status142683
|
||||
Node: Signals144745
|
||||
Node: Shell Scripts149696
|
||||
Node: Shell Builtin Commands152997
|
||||
Node: Bourne Shell Builtins155341
|
||||
Node: Bash Builtins182063
|
||||
Node: Modifying Shell Behavior219802
|
||||
Node: The Set Builtin220147
|
||||
Node: The Shopt Builtin232144
|
||||
Node: Special Builtins249200
|
||||
Node: Shell Variables250192
|
||||
Node: Bourne Shell Variables250629
|
||||
Node: Bash Variables253140
|
||||
Node: Bash Features292427
|
||||
Node: Invoking Bash293444
|
||||
Node: Bash Startup Files300031
|
||||
Node: Interactive Shells305276
|
||||
Node: What is an Interactive Shell?305687
|
||||
Node: Is this Shell Interactive?306352
|
||||
Node: Interactive Shell Behavior307179
|
||||
Node: Bash Conditional Expressions310943
|
||||
Node: Shell Arithmetic316363
|
||||
Node: Aliases319693
|
||||
Node: Arrays322830
|
||||
Node: The Directory Stack330536
|
||||
Node: Directory Stack Builtins331336
|
||||
Node: Controlling the Prompt335784
|
||||
Node: The Restricted Shell338671
|
||||
Node: Bash POSIX Mode341767
|
||||
Node: Shell Compatibility Mode361186
|
||||
Node: Job Control370196
|
||||
Node: Job Control Basics370656
|
||||
Node: Job Control Builtins377027
|
||||
Node: Job Control Variables383818
|
||||
Node: Command Line Editing385052
|
||||
Node: Introduction and Notation386758
|
||||
Node: Readline Interaction389113
|
||||
Node: Readline Bare Essentials390304
|
||||
Node: Readline Movement Commands392115
|
||||
Node: Readline Killing Commands393114
|
||||
Node: Readline Arguments395140
|
||||
Node: Searching396233
|
||||
Node: Readline Init File398479
|
||||
Node: Readline Init File Syntax399785
|
||||
Node: Conditional Init Constructs426739
|
||||
Node: Sample Init File431127
|
||||
Node: Bindable Readline Commands434250
|
||||
Node: Commands For Moving435791
|
||||
Node: Commands For History438258
|
||||
Node: Commands For Text443652
|
||||
Node: Commands For Killing447780
|
||||
Node: Numeric Arguments450571
|
||||
Node: Commands For Completion451726
|
||||
Node: Keyboard Macros457425
|
||||
Node: Miscellaneous Commands458129
|
||||
Node: Readline vi Mode465675
|
||||
Node: Programmable Completion466655
|
||||
Node: Programmable Completion Builtins476394
|
||||
Node: A Programmable Completion Example488134
|
||||
Node: Using History Interactively493482
|
||||
Node: Bash History Facilities494166
|
||||
Node: Bash History Builtins497904
|
||||
Node: History Interaction505502
|
||||
Node: Event Designators510455
|
||||
Node: Word Designators512036
|
||||
Node: Modifiers514431
|
||||
Node: Installing Bash516371
|
||||
Node: Basic Installation517490
|
||||
Node: Compilers and Options521369
|
||||
Node: Compiling For Multiple Architectures522122
|
||||
Node: Installation Names523878
|
||||
Node: Specifying the System Type526115
|
||||
Node: Sharing Defaults526864
|
||||
Node: Operation Controls527581
|
||||
Node: Optional Features528603
|
||||
Node: Reporting Bugs541329
|
||||
Node: Major Differences From The Bourne Shell542689
|
||||
Node: GNU Free Documentation License564119
|
||||
Node: Indexes589299
|
||||
Node: Builtin Index589753
|
||||
Node: Reserved Word Index596854
|
||||
Node: Variable Index599302
|
||||
Node: Function Index616718
|
||||
Node: Concept Index630854
|
||||
Node: Top904
|
||||
Node: Introduction2848
|
||||
Node: What is Bash?3064
|
||||
Node: What is a shell?4200
|
||||
Node: Definitions6813
|
||||
Node: Basic Shell Features10143
|
||||
Node: Shell Syntax11370
|
||||
Node: Shell Operation12400
|
||||
Node: Quoting13694
|
||||
Node: Escape Character15035
|
||||
Node: Single Quotes15573
|
||||
Node: Double Quotes15925
|
||||
Node: ANSI-C Quoting17273
|
||||
Node: Locale Translation18670
|
||||
Node: Creating Internationalized Scripts20076
|
||||
Node: Comments24277
|
||||
Node: Shell Commands25047
|
||||
Node: Reserved Words25989
|
||||
Node: Simple Commands27135
|
||||
Node: Pipelines27800
|
||||
Node: Lists31059
|
||||
Node: Compound Commands33011
|
||||
Node: Looping Constructs34023
|
||||
Node: Conditional Constructs36575
|
||||
Node: Command Grouping51715
|
||||
Node: Coprocesses53210
|
||||
Node: GNU Parallel55899
|
||||
Node: Shell Functions56820
|
||||
Node: Shell Parameters65271
|
||||
Node: Positional Parameters70175
|
||||
Node: Special Parameters71268
|
||||
Node: Shell Expansions74732
|
||||
Node: Brace Expansion76924
|
||||
Node: Tilde Expansion80263
|
||||
Node: Shell Parameter Expansion83221
|
||||
Node: Command Substitution103871
|
||||
Node: Arithmetic Expansion107725
|
||||
Node: Process Substitution108904
|
||||
Node: Word Splitting110015
|
||||
Node: Filename Expansion112462
|
||||
Node: Pattern Matching115689
|
||||
Node: Quote Removal121458
|
||||
Node: Redirections121765
|
||||
Node: Executing Commands132024
|
||||
Node: Simple Command Expansion132694
|
||||
Node: Command Search and Execution134805
|
||||
Node: Command Execution Environment137252
|
||||
Node: Environment140781
|
||||
Node: Exit Status142687
|
||||
Node: Signals144749
|
||||
Node: Shell Scripts149700
|
||||
Node: Shell Builtin Commands153001
|
||||
Node: Bourne Shell Builtins155345
|
||||
Node: Bash Builtins182067
|
||||
Node: Modifying Shell Behavior219806
|
||||
Node: The Set Builtin220151
|
||||
Node: The Shopt Builtin232148
|
||||
Node: Special Builtins249204
|
||||
Node: Shell Variables250196
|
||||
Node: Bourne Shell Variables250633
|
||||
Node: Bash Variables253144
|
||||
Node: Bash Features292431
|
||||
Node: Invoking Bash293448
|
||||
Node: Bash Startup Files300035
|
||||
Node: Interactive Shells305280
|
||||
Node: What is an Interactive Shell?305691
|
||||
Node: Is this Shell Interactive?306356
|
||||
Node: Interactive Shell Behavior307183
|
||||
Node: Bash Conditional Expressions310947
|
||||
Node: Shell Arithmetic316367
|
||||
Node: Aliases319697
|
||||
Node: Arrays322834
|
||||
Node: The Directory Stack330540
|
||||
Node: Directory Stack Builtins331340
|
||||
Node: Controlling the Prompt335788
|
||||
Node: The Restricted Shell338675
|
||||
Node: Bash POSIX Mode341771
|
||||
Node: Shell Compatibility Mode361590
|
||||
Node: Job Control370600
|
||||
Node: Job Control Basics371060
|
||||
Node: Job Control Builtins377431
|
||||
Node: Job Control Variables384222
|
||||
Node: Command Line Editing385456
|
||||
Node: Introduction and Notation387162
|
||||
Node: Readline Interaction389517
|
||||
Node: Readline Bare Essentials390708
|
||||
Node: Readline Movement Commands392519
|
||||
Node: Readline Killing Commands393518
|
||||
Node: Readline Arguments395544
|
||||
Node: Searching396637
|
||||
Node: Readline Init File398883
|
||||
Node: Readline Init File Syntax400189
|
||||
Node: Conditional Init Constructs427143
|
||||
Node: Sample Init File431531
|
||||
Node: Bindable Readline Commands434654
|
||||
Node: Commands For Moving436195
|
||||
Node: Commands For History438662
|
||||
Node: Commands For Text444056
|
||||
Node: Commands For Killing448184
|
||||
Node: Numeric Arguments450975
|
||||
Node: Commands For Completion452130
|
||||
Node: Keyboard Macros457829
|
||||
Node: Miscellaneous Commands458533
|
||||
Node: Readline vi Mode466079
|
||||
Node: Programmable Completion467059
|
||||
Node: Programmable Completion Builtins476798
|
||||
Node: A Programmable Completion Example488538
|
||||
Node: Using History Interactively493886
|
||||
Node: Bash History Facilities494570
|
||||
Node: Bash History Builtins498308
|
||||
Node: History Interaction505906
|
||||
Node: Event Designators510859
|
||||
Node: Word Designators512440
|
||||
Node: Modifiers514835
|
||||
Node: Installing Bash516775
|
||||
Node: Basic Installation517894
|
||||
Node: Compilers and Options521773
|
||||
Node: Compiling For Multiple Architectures522526
|
||||
Node: Installation Names524282
|
||||
Node: Specifying the System Type526519
|
||||
Node: Sharing Defaults527268
|
||||
Node: Operation Controls527985
|
||||
Node: Optional Features529007
|
||||
Node: Reporting Bugs541733
|
||||
Node: Major Differences From The Bourne Shell543093
|
||||
Node: GNU Free Documentation License564523
|
||||
Node: Indexes589703
|
||||
Node: Builtin Index590157
|
||||
Node: Reserved Word Index597258
|
||||
Node: Variable Index599706
|
||||
Node: Function Index617122
|
||||
Node: Concept Index631258
|
||||
|
||||
End Tag Table
|
||||
|
||||
|
||||
@@ -9707,6 +9707,13 @@ the @code{command} builtin or another non-special builtin fails.
|
||||
There is ambiguity in @sc{posix} about this.
|
||||
@end ignore
|
||||
|
||||
@item
|
||||
Bash does not perform redirections before expanding variable assignments
|
||||
preceding a simple command; it does not allow the redirections access to
|
||||
the results of the variable assignments, but any side effects of expanding
|
||||
the redirections take place first.
|
||||
If compiled in @i{strict posix} mode, Bash performs redirections first.
|
||||
|
||||
@item
|
||||
As noted above, Bash requires the @code{xpg_echo} option to be enabled for
|
||||
the @code{echo} builtin to be fully conformant.
|
||||
|
||||
+3
-3
@@ -2,10 +2,10 @@
|
||||
Copyright (C) 1988-2026 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Wed Jan 14 15:46:16 EST 2026
|
||||
@set LASTCHANGE Fri Feb 27 12:23:35 EST 2026
|
||||
|
||||
@set EDITION 5.3
|
||||
@set VERSION 5.3
|
||||
|
||||
@set UPDATED 14 January 2026
|
||||
@set UPDATED-MONTH January 2026
|
||||
@set UPDATED 27 February 2026
|
||||
@set UPDATED-MONTH February 2026
|
||||
|
||||
+43
-6
@@ -106,6 +106,7 @@ extern int errno;
|
||||
# include <mbstr.h> /* mbschr */
|
||||
#endif
|
||||
|
||||
extern WORD_LIST *subst_assign_varlist;
|
||||
extern int command_string_index;
|
||||
extern char *the_printed_command;
|
||||
extern time_t shell_start_time;
|
||||
@@ -4272,10 +4273,15 @@ execute_null_command (REDIRECT *redirects, int pipe_in, int pipe_out, int async)
|
||||
if (code)
|
||||
exit (EXECUTION_FAILURE);
|
||||
|
||||
if (do_redirections (redirects, RX_ACTIVE) == 0)
|
||||
exit (EXECUTION_SUCCESS);
|
||||
else
|
||||
if (do_redirections (redirects, RX_ACTIVE) != 0)
|
||||
exit (EXECUTION_FAILURE);
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
if (posixly_correct)
|
||||
exit (subst_assign_varlist ? expand_assignment_statements ((char *)NULL, 1) : EXECUTION_SUCCESS);
|
||||
else
|
||||
#endif
|
||||
exit (EXECUTION_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4300,6 +4306,11 @@ execute_null_command (REDIRECT *redirects, int pipe_in, int pipe_out, int async)
|
||||
cleanup_redirects (redirection_undo_list);
|
||||
redirection_undo_list = (REDIRECT *)NULL;
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
if (r == 0 && posixly_correct && subst_assign_varlist)
|
||||
expand_assignment_statements ((char *)NULL, 1);
|
||||
#endif
|
||||
|
||||
if (r != 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
else if (last_command_subst_pid != NO_PID)
|
||||
@@ -5608,6 +5619,11 @@ execute_subshell_builtin_or_function (WORD_LIST *words, REDIRECT *redirects,
|
||||
add_unwind_protect (uw_cleanup_redirects, (char *)saved_undo_list);
|
||||
}
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
if (posixly_correct && subst_assign_varlist)
|
||||
expand_assignment_statements (this_command_name, 0);
|
||||
#endif
|
||||
|
||||
if (builtin)
|
||||
{
|
||||
int subshell_exit_value;
|
||||
@@ -5743,6 +5759,11 @@ execute_builtin_or_function (WORD_LIST *words,
|
||||
add_unwind_protect (uw_cleanup_redirects, (char *)saved_undo_list);
|
||||
}
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
if (posixly_correct && subst_assign_varlist)
|
||||
expand_assignment_statements (this_command_name, 0);
|
||||
#endif
|
||||
|
||||
if (builtin)
|
||||
result = execute_builtin (builtin, words, flags, 0);
|
||||
else
|
||||
@@ -5920,8 +5941,13 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line,
|
||||
if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE && (subshell_environment & SUBSHELL_PIPE) == 0)
|
||||
adjust_shell_level (-1);
|
||||
|
||||
maybe_make_export_env ();
|
||||
put_command_name_into_env (command);
|
||||
#if defined (STRICT_POSIX)
|
||||
if (posixly_correct == 0 || subst_assign_varlist == 0) /* Done below. */
|
||||
#endif
|
||||
{
|
||||
maybe_make_export_env ();
|
||||
put_command_name_into_env (command);
|
||||
}
|
||||
}
|
||||
else if (command == 0 && notfound_str == 0) /* make sure */
|
||||
init_notfound_str ();
|
||||
@@ -6001,9 +6027,20 @@ execute_disk_command (WORD_LIST *words, REDIRECT *redirects, char *command_line,
|
||||
exit (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
#if defined (STRICT_POSIX)
|
||||
if (posixly_correct && subst_assign_varlist)
|
||||
{
|
||||
expand_assignment_statements (command, 0);
|
||||
|
||||
maybe_make_export_env ();
|
||||
put_command_name_into_env (command);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (PROCESS_SUBSTITUTION) && !defined (HAVE_DEV_FD)
|
||||
/* This should only contain FIFOs created as part of redirection
|
||||
expansion. */
|
||||
expansion and expanding the rhs of assignment statements in
|
||||
posix mode. */
|
||||
unlink_all_fifos ();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# environ.m4
|
||||
# serial 8
|
||||
dnl Copyright (C) 2001-2004, 2006-2026 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
dnl This file is offered as-is, without any warranty.
|
||||
|
||||
AC_DEFUN_ONCE([gl_ENVIRON],
|
||||
[
|
||||
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
|
||||
dnl Persuade glibc <unistd.h> to declare environ.
|
||||
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
|
||||
|
||||
AC_CHECK_HEADERS_ONCE([unistd.h])
|
||||
gt_CHECK_VAR_DECL(
|
||||
[#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
/* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>. */
|
||||
#include <stdlib.h>
|
||||
],
|
||||
[environ])
|
||||
if test $gt_cv_var_environ_declaration != yes; then
|
||||
HAVE_DECL_ENVIRON=0
|
||||
fi
|
||||
])
|
||||
|
||||
# Check if a variable is properly declared.
|
||||
# gt_CHECK_VAR_DECL(includes,variable)
|
||||
AC_DEFUN([gt_CHECK_VAR_DECL],
|
||||
[
|
||||
define([gt_cv_var], [gt_cv_var_]$2[_declaration])
|
||||
AC_CACHE_CHECK([if $2 is properly declared], [gt_cv_var],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[[$1
|
||||
typedef struct { int foo; } foo_t;
|
||||
extern foo_t $2;]],
|
||||
[[$2.foo = 1;]])],
|
||||
[gt_cv_var=no],
|
||||
[gt_cv_var=yes])])
|
||||
if test $gt_cv_var = yes; then
|
||||
AC_DEFINE([HAVE_]m4_translit($2, [a-z], [A-Z])[_DECL], 1,
|
||||
[Define if you have the declaration of $2.])
|
||||
fi
|
||||
undefine([gt_cv_var])
|
||||
])
|
||||
+1
-1
@@ -843,7 +843,7 @@ print_if_command (IF_COM *if_command)
|
||||
semicolon ();
|
||||
if (was_heredoc)
|
||||
{
|
||||
indent (indentation_amount);
|
||||
indent (indentation);
|
||||
cprintf ("then\n");
|
||||
was_heredoc = 0;
|
||||
}
|
||||
|
||||
@@ -12722,10 +12722,12 @@ separate_out_assignments (WORD_LIST *tlist)
|
||||
#define WEXP_TILDEEXP 0x004
|
||||
#define WEXP_PARAMEXP 0x008
|
||||
#define WEXP_PATHEXP 0x010
|
||||
#define WEXP_DEFERVARS 0x020
|
||||
|
||||
/* All of the expansions, including variable assignments at the start of
|
||||
the list. */
|
||||
#define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
|
||||
#define WEXP_POSIX (WEXP_ALL|WEXP_DEFERVARS)
|
||||
|
||||
/* All of the expansions except variable assignments at the start of
|
||||
the list. */
|
||||
@@ -12739,11 +12741,16 @@ separate_out_assignments (WORD_LIST *tlist)
|
||||
/* Take the list of words in LIST and do the various substitutions. Return
|
||||
a new list of words which is the expanded list, and without things like
|
||||
variable assignments. */
|
||||
|
||||
/* This is only called to expand the words of a simple command, so it can
|
||||
pay attention to posix mode treatment of variable assignments. */
|
||||
WORD_LIST *
|
||||
expand_words (WORD_LIST *list)
|
||||
{
|
||||
#if defined (STRICT_POSIX)
|
||||
return (expand_word_list_internal (list, posixly_correct ? WEXP_POSIX : WEXP_ALL));
|
||||
#else
|
||||
return (expand_word_list_internal (list, WEXP_ALL));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Same as expand_words (), but doesn't hack variable or environment
|
||||
@@ -13404,7 +13411,7 @@ expand_word_list_internal (WORD_LIST *list, int eflags)
|
||||
garglist = new_list = separate_out_assignments (new_list);
|
||||
if (new_list == 0)
|
||||
{
|
||||
if (subst_assign_varlist)
|
||||
if (subst_assign_varlist && (eflags & WEXP_DEFERVARS) == 0)
|
||||
expand_assignment_statements ((char *)NULL, 1);
|
||||
|
||||
return ((WORD_LIST *)NULL);
|
||||
@@ -13438,7 +13445,7 @@ expand_word_list_internal (WORD_LIST *list, int eflags)
|
||||
new_list = dequote_list (new_list);
|
||||
}
|
||||
|
||||
if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
|
||||
if (((eflags & (WEXP_VARASSIGN|WEXP_DEFERVARS)) == WEXP_VARASSIGN) && subst_assign_varlist)
|
||||
expand_assignment_statements ((new_list && new_list->word) ? new_list->word->word : (char *)NULL, new_list == 0);
|
||||
|
||||
return (new_list);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* subst.h -- Names of externally visible functions in subst.c. */
|
||||
|
||||
/* Copyright (C) 1993-2024 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1993-2026 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
exec 9<>/dev/tcp/129.22.8.162/25
|
||||
|
||||
read banner <&9
|
||||
echo "$banner"
|
||||
|
||||
echo quit >&9
|
||||
|
||||
read msg <&9
|
||||
echo "$msg"
|
||||
|
||||
exec 9<&-
|
||||
|
||||
# nifty date command that queries the date/time server
|
||||
cat < /dev/tcp/129.22.8.102/13
|
||||
|
||||
exit 0
|
||||
@@ -1,388 +0,0 @@
|
||||
export LC_COLLATE=C
|
||||
#
|
||||
# test the shell globbing
|
||||
#
|
||||
expect()
|
||||
{
|
||||
echo expect "$@"
|
||||
}
|
||||
|
||||
# First, a test that bash-2.01.1 fails
|
||||
${THIS_SH} ./glob1.sub
|
||||
|
||||
MYDIR=$PWD # save where we are
|
||||
|
||||
TESTDIR=/tmp/glob-test
|
||||
mkdir $TESTDIR
|
||||
builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
|
||||
rm -rf *
|
||||
|
||||
touch a b c d abc abd abe bb bcd ca cb dd de Beware
|
||||
mkdir bdir
|
||||
|
||||
# see if `regular' globbing works right
|
||||
expect '<a> <abc> <abd> <abe> <X*>'
|
||||
recho a* X*
|
||||
|
||||
expect '<a> <abc> <abd> <abe>'
|
||||
recho \a*
|
||||
|
||||
# see if null glob expansion works
|
||||
shopt -s nullglob
|
||||
|
||||
expect '<a> <abc> <abd> <abe>'
|
||||
recho a* X*
|
||||
|
||||
shopt -u nullglob
|
||||
|
||||
# see if the failglob option works
|
||||
|
||||
mkdir tmp
|
||||
touch tmp/l1 tmp/l2 tmp/l3
|
||||
builtin echo tmp/l[12] tmp/*4 tmp/*3
|
||||
shopt -s failglob
|
||||
builtin echo tmp/l[12] tmp/*4 tmp/*3
|
||||
rm -r tmp
|
||||
shopt -u failglob
|
||||
|
||||
# see if the code that expands directories only works
|
||||
expect '<bdir/>'
|
||||
recho b*/
|
||||
|
||||
# Test quoted and unquoted globbing characters
|
||||
expect '<*>'
|
||||
recho \*
|
||||
|
||||
expect '<a*>'
|
||||
recho 'a*'
|
||||
|
||||
expect '<a*>'
|
||||
recho a\*
|
||||
|
||||
expect '<c> <ca> <cb> <a*> <*q*>'
|
||||
recho c* a\* *q*
|
||||
|
||||
expect '<**>'
|
||||
recho "*"*
|
||||
|
||||
expect '<**>'
|
||||
recho \**
|
||||
|
||||
expect '<\.\./*/>'
|
||||
recho "\.\./*/"
|
||||
|
||||
expect '<s/\..*//>'
|
||||
recho 's/\..*//'
|
||||
|
||||
# Pattern from Larry Wall's Configure that caused bash to blow up
|
||||
expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>'
|
||||
recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/"
|
||||
|
||||
# Make sure character classes work properly
|
||||
|
||||
expect '<abc> <abd> <abe> <bb> <cb>'
|
||||
recho [a-c]b*
|
||||
|
||||
expect '<abd> <abe> <bb> <bcd> <bdir> <ca> <cb> <dd> <de>'
|
||||
recho [a-y]*[^c]
|
||||
|
||||
expect '<abd> <abe>'
|
||||
recho a*[^c]
|
||||
|
||||
touch a-b aXb
|
||||
expect '<a-b> <aXb>'
|
||||
recho a[X-]b
|
||||
|
||||
touch .x .y
|
||||
expect '<Beware> <d> <dd> <de>'
|
||||
recho [^a-c]*
|
||||
|
||||
# Make sure that filenames with embedded globbing characters are handled
|
||||
# properly
|
||||
mkdir a\*b
|
||||
> a\*b/ooo
|
||||
|
||||
expect '<a*b/ooo>'
|
||||
recho a\*b/*
|
||||
|
||||
expect '<a*b/ooo>'
|
||||
recho a\*?/*
|
||||
|
||||
expect '<no match>'
|
||||
cmd='echo !7'
|
||||
case "$cmd" in
|
||||
*\\!*) echo match ;;
|
||||
*) echo no match ;;
|
||||
esac
|
||||
|
||||
expect '<not there>'
|
||||
file='r.*'
|
||||
case $file in
|
||||
*.\*) echo not there ;;
|
||||
*) echo there ;;
|
||||
esac
|
||||
|
||||
# examples from the Posix.2 spec (d11.2, p. 243)
|
||||
expect '<abc>'
|
||||
recho a[b]c
|
||||
|
||||
expect '<abc>'
|
||||
recho a["b"]c
|
||||
|
||||
expect '<abc>'
|
||||
recho a[\b]c
|
||||
|
||||
expect '<abc>'
|
||||
recho a?c
|
||||
|
||||
expect '<match 1>'
|
||||
case abc in
|
||||
a"b"c) echo 'match 1' ;;
|
||||
*) echo 'BAD match 1' ;;
|
||||
esac
|
||||
|
||||
expect '<match 2>'
|
||||
case abc in
|
||||
a*c) echo 'match 2' ;;
|
||||
*) echo 'BAD match 2' ;;
|
||||
esac
|
||||
|
||||
expect '<ok 1>'
|
||||
case abc in
|
||||
"a?c") echo 'bad 1' ;;
|
||||
*) echo 'ok 1' ;;
|
||||
esac
|
||||
|
||||
expect '<ok 2>'
|
||||
case abc in
|
||||
a\*c) echo 'bad 2' ;;
|
||||
*) echo 'ok 2' ;;
|
||||
esac
|
||||
|
||||
expect '<ok 3>'
|
||||
case abc in
|
||||
a\[b]c) echo 'bad 3' ;;
|
||||
*) echo 'ok 3' ;;
|
||||
esac
|
||||
|
||||
expect '<ok 4>'
|
||||
case "$nosuchvar" in
|
||||
"") echo 'ok 4' ;;
|
||||
*) echo 'bad 4' ;;
|
||||
esac
|
||||
|
||||
# This is very odd, but sh and ksh seem to agree
|
||||
expect '<ok 5>'
|
||||
case abc in
|
||||
a["\b"]c) echo 'ok 5' ;;
|
||||
*) echo 'bad 5' ;;
|
||||
esac
|
||||
|
||||
mkdir man
|
||||
mkdir man/man1
|
||||
touch man/man1/bash.1
|
||||
expect '<man/man1/bash.1>'
|
||||
recho */man*/bash.*
|
||||
expect '<man/man1/bash.1>'
|
||||
recho $(echo */man*/bash.*)
|
||||
expect '<man/man1/bash.1>'
|
||||
recho "$(echo */man*/bash.*)"
|
||||
|
||||
# tests with multiple `*'s
|
||||
case abc in
|
||||
a***c) echo ok 1;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
a*****?c) echo ok 2;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
?*****??) echo ok 3;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
*****??) echo ok 4;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
*****??c) echo ok 5;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
?*****?c) echo ok 6;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
?***?****c) echo ok 7;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
?***?****?) echo ok 8;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
?***?****) echo ok 9;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
*******c) echo ok 10;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
*******?) echo ok 11;;
|
||||
esac
|
||||
|
||||
case abcdecdhjk in
|
||||
a*cd**?**??k) echo ok 20;;
|
||||
esac
|
||||
|
||||
case abcdecdhjk in
|
||||
a**?**cd**?**??k) echo ok 21;;
|
||||
esac
|
||||
|
||||
case abcdecdhjk in
|
||||
a**?**cd**?**??k***) echo ok 22;;
|
||||
esac
|
||||
|
||||
case abcdecdhjk in
|
||||
a**?**cd**?**??***k) echo ok 23;;
|
||||
esac
|
||||
|
||||
case abcdecdhjk in
|
||||
a**?**cd**?**??***k**) echo ok 24;;
|
||||
esac
|
||||
|
||||
case abcdecdhjk in
|
||||
a****c**?**??*****) echo ok 25;;
|
||||
esac
|
||||
|
||||
case '-' in
|
||||
[-abc]) echo ok 26 ;;
|
||||
esac
|
||||
|
||||
case '-' in
|
||||
[abc-]) echo ok 27 ;;
|
||||
esac
|
||||
|
||||
case '\' in
|
||||
\\) echo ok 28 ;;
|
||||
esac
|
||||
|
||||
case '\' in
|
||||
[\\]) echo ok 29 ;;
|
||||
esac
|
||||
|
||||
case '\' in
|
||||
'\') echo ok 30 ;;
|
||||
esac
|
||||
|
||||
case '[' in
|
||||
[[]) echo ok 31 ;;
|
||||
esac
|
||||
|
||||
# a `[' without a closing `]' is just another character to match, in the
|
||||
# bash implementation
|
||||
case '[' in
|
||||
[) echo ok 32 ;;
|
||||
esac
|
||||
|
||||
case '[abc' in
|
||||
[*) echo 'ok 33';;
|
||||
esac
|
||||
|
||||
# a right bracket shall lose its special meaning and represent itself in
|
||||
# a bracket expression if it occurs first in the list. -- POSIX.2 2.8.3.2
|
||||
case ']' in
|
||||
[]]) echo ok 34 ;;
|
||||
esac
|
||||
|
||||
case '-' in
|
||||
[]-]) echo ok 35 ;;
|
||||
esac
|
||||
|
||||
# a backslash should just escape the next character in this context
|
||||
case p in
|
||||
[a-\z]) echo ok 36 ;;
|
||||
esac
|
||||
|
||||
# this was a bug in all versions up to bash-2.04-release
|
||||
case "/tmp" in
|
||||
[/\\]*) echo ok 37 ;;
|
||||
esac
|
||||
|
||||
# none of these should output anything
|
||||
|
||||
case abc in
|
||||
??**********?****?) echo bad 1;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
??**********?****c) echo bad 2;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
?************c****?****) echo bad 3;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
*c*?**) echo bad 4;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
a*****c*?**) echo bad 5;;
|
||||
esac
|
||||
|
||||
case abc in
|
||||
a********???*******) echo bad 6;;
|
||||
esac
|
||||
|
||||
case 'a' in
|
||||
[]) echo bad 7 ;;
|
||||
esac
|
||||
|
||||
case '[' in
|
||||
[abc) echo bad 8;;
|
||||
esac
|
||||
|
||||
# let's start testing the case-insensitive globbing code
|
||||
recho b*
|
||||
|
||||
shopt -s nocaseglob
|
||||
recho b*
|
||||
|
||||
recho [b]*
|
||||
shopt -u nocaseglob
|
||||
|
||||
# make sure set -f works right
|
||||
set -f
|
||||
recho *
|
||||
set +f
|
||||
|
||||
# test out the GLOBIGNORE code
|
||||
GLOBIGNORE='.*:*c:*e:?'
|
||||
recho *
|
||||
|
||||
GLOBIGNORE='.*:*b:*d:?'
|
||||
recho *
|
||||
|
||||
# see if GLOBIGNORE can substitute for `set -f'
|
||||
GLOBIGNORE='.*:*'
|
||||
recho *
|
||||
|
||||
unset GLOBIGNORE
|
||||
expect '<man/man1/bash.1>'
|
||||
recho */man*/bash.*
|
||||
|
||||
# make sure null values for GLOBIGNORE have no effect
|
||||
GLOBIGNORE=
|
||||
expect '<man/man1/bash.1>'
|
||||
recho */man*/bash.*
|
||||
|
||||
# this is for the benefit of pure coverage, so it writes the pcv file
|
||||
# in the right place, and for gprof
|
||||
builtin cd $MYDIR
|
||||
|
||||
rm -rf $TESTDIR
|
||||
|
||||
exit 0
|
||||
@@ -1 +0,0 @@
|
||||
a:b:c
|
||||
@@ -1,5 +0,0 @@
|
||||
OIFS="$IFS"
|
||||
IFS=":$IFS"
|
||||
eval foo="a:b:c"
|
||||
IFS="$OIFS"
|
||||
echo $foo
|
||||
@@ -1 +0,0 @@
|
||||
a:b:c
|
||||
@@ -1,9 +0,0 @@
|
||||
OIFS=$IFS
|
||||
IFS=":$IFS"
|
||||
foo=$(echo a:b:c)
|
||||
IFS=$OIFS
|
||||
|
||||
for i in $foo
|
||||
do
|
||||
echo $i
|
||||
done
|
||||
@@ -1 +0,0 @@
|
||||
a:b:c
|
||||
@@ -1,9 +0,0 @@
|
||||
OIFS=$IFS
|
||||
IFS=":$IFS"
|
||||
foo=`echo a:b:c`
|
||||
IFS=$OIFS
|
||||
|
||||
for i in $foo
|
||||
do
|
||||
echo $i
|
||||
done
|
||||
@@ -1,4 +0,0 @@
|
||||
echo before calling input-line.sub
|
||||
${THIS_SH} < ./input-line.sub
|
||||
this line for input-line.sub
|
||||
echo finished with input-line.sub
|
||||
@@ -1,6 +0,0 @@
|
||||
set -e
|
||||
if set +e
|
||||
then
|
||||
false
|
||||
fi
|
||||
echo hi
|
||||
@@ -1 +0,0 @@
|
||||
hi
|
||||
@@ -1,81 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
typeset -i m2 m1 M n2 n1 N m n
|
||||
typeset -i MM=5 NN=5
|
||||
|
||||
case $# in
|
||||
0) :
|
||||
;;
|
||||
1) MM=$1; NN=$1
|
||||
;;
|
||||
2) MM=$1; NN=$2
|
||||
;;
|
||||
*) echo 1>&2 "Usage: $0 [m [n]]"
|
||||
;;
|
||||
esac
|
||||
|
||||
EMPTYLINE=: # echo
|
||||
echo 'a = { ' # mathematica
|
||||
|
||||
let "M=1" # for (M=1; M<=MM; M++)
|
||||
while let "M <= MM"; do
|
||||
let "N=1" # for (N=1; N<=NN; N++)
|
||||
while let "N <= NN"; do
|
||||
|
||||
let "m1 = M - 1"
|
||||
let "m2 = M + 1"
|
||||
let "n1 = N - 1"
|
||||
let "n2 = N + 1"
|
||||
|
||||
|
||||
echo -n '{ ' # math
|
||||
let "m=1" # for(m=1; m<=MM; m++)
|
||||
while let "m <= MM"; do
|
||||
let "n=1" # for(n=1; n<=NN; n++)
|
||||
while let "n <= NN"; do
|
||||
|
||||
let "x = (m-m1)*(m-M)*(m-m2)"
|
||||
let "y = (n-n1)*(n-N)*(n-n2)"
|
||||
|
||||
if let "(x*x + (n-N)*(n-N)) * ((m-M)*(m-M) + y*y)"; then
|
||||
echo -n "0,"
|
||||
else # neighbour
|
||||
echo -n "1,"
|
||||
fi
|
||||
|
||||
let "n=n+1"
|
||||
done
|
||||
echo -n " "; let "m=m+1" # ". "
|
||||
done
|
||||
echo '},'
|
||||
|
||||
|
||||
let "N=N+1"
|
||||
$EMPTYLINE
|
||||
done
|
||||
$EMPTYLINE
|
||||
let "M=M+1"
|
||||
done
|
||||
|
||||
echo '}'
|
||||
|
||||
|
||||
|
||||
echo -n 'o = { '
|
||||
let "m=1"
|
||||
while let "m <= MM"; do
|
||||
let "n=1"
|
||||
while let "n <= NN"; do
|
||||
echo -n "1,"
|
||||
let "n=n+1"
|
||||
done
|
||||
let "m=m+1"
|
||||
done
|
||||
echo " }"
|
||||
|
||||
|
||||
echo 'x = LinearSolve[a,o] '
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# originally from Mike Haertel
|
||||
foo() { case $1 in a*) ;; *) ;; esac ;}
|
||||
bar() { case $1 in [abc]*) ;; *);; esac ;}
|
||||
baz() { case $1 in xyzzy) ;; *) ;; esac ;}
|
||||
for x in /usr/lib/*/*
|
||||
do
|
||||
foo $x
|
||||
bar $x
|
||||
baz $x
|
||||
done
|
||||
@@ -1,11 +0,0 @@
|
||||
# interactive
|
||||
|
||||
# from tty
|
||||
read -n 3 -p 'enter three chars: ' xyz
|
||||
echo
|
||||
echo $xyz
|
||||
|
||||
# using readline
|
||||
read -p 'enter 3 chars: ' -e -n 3 abc
|
||||
# readline outputs a newline for us, so we don't need the extra echo
|
||||
echo $abc
|
||||
@@ -1,11 +0,0 @@
|
||||
# interactive
|
||||
|
||||
# from tty
|
||||
read -n 3 -p 'enter three chars: ' xyz
|
||||
echo
|
||||
echo $xyz
|
||||
|
||||
# using readline
|
||||
read -p 'enter 3 chars: ' -e -n 3 abc
|
||||
# readline outputs a newline for us, so we don't need the extra echo
|
||||
echo $abc
|
||||
@@ -1,17 +0,0 @@
|
||||
read line1
|
||||
|
||||
echo read line 1 \"$line1\"
|
||||
|
||||
exec 4<&0
|
||||
|
||||
exec 0</dev/tty
|
||||
|
||||
read line2
|
||||
|
||||
echo line read from tty = \"$line2\"
|
||||
|
||||
exec 0<&4
|
||||
|
||||
read line3
|
||||
|
||||
echo read line 3 \"$line3\"
|
||||
@@ -1,12 +0,0 @@
|
||||
This is Geoff Collyer's `sh' regression test. It will run each test
|
||||
on sh and ../../bash, and on ksh if you have it. I have `real' ksh;
|
||||
the PD ksh is different and will fail some of the tests.
|
||||
|
||||
Expect some small variations in the sh and bash output, since some
|
||||
of the tests work from the output of `date' or on the current dat
|
||||
returned by `getdate'.
|
||||
|
||||
Don't expect `getdate' to exist unless you're running C News. If you
|
||||
don't have it, run
|
||||
|
||||
make -f getdate.mk getdate
|
||||
@@ -1,152 +0,0 @@
|
||||
Newsgroups: comp.os.coherent
|
||||
Subject: sh clones evaluated (was Re: C News)
|
||||
Organization: Software Tool & Die Netnews Research Center
|
||||
References: <138198@allan.sublink.org> <920725204@umunk.GUN.de>
|
||||
<9207260813.30@rmkhome.UUCP> <1992Jul27.200244.2456@acme.gen.nz>
|
||||
<Bs0x7K.2pp@world.std.com> <9207291604.00@rmkhome.UUCP>
|
||||
<Bs84t1.3Fx@world.std.com> <9208011403.38@rmkhome.UUCP>
|
||||
|
||||
I've reevaluated the allegedly-sh-compatible shells I have on hand (sh,
|
||||
bash, ash, zsh and a redistributable ksh). bash seems to have improved
|
||||
since I last looked at it and seems to run inews and subordinates
|
||||
correctly, and passes the diagnostic tests I extracted from inews and
|
||||
anne.jones. ash, zsh and redistributable ksh each fail three of the six
|
||||
tests. This saddens me, as ash is an elegant and relatively small piece
|
||||
of work, whereas bash is bloated and complicated.
|
||||
|
||||
I've enclosed the test scripts (shx?), driver script (shx) and results
|
||||
(log) below. A couple caveats: shx4 (a quoting test) uses the C News
|
||||
getdate command; there may be newer versions of the shells tested - this
|
||||
evaluation is decidedly informal. Here's a quick summary: sh and bash
|
||||
passed all tests; ash can't parse "<&$fd" and doesn't understand quoting;
|
||||
redistributable ksh dumps core on a newline inside backquotes, doesn't
|
||||
understand quoting, and botches waiting on background processes; zsh
|
||||
doesn't understand sh quoting (in particular, it sees ! as a job control
|
||||
character, even inside quotes), and botches waiting for background
|
||||
processes.
|
||||
|
||||
|
||||
# To unbundle, sh this file
|
||||
echo log 1>&2
|
||||
sed 's/^X//' >log <<'!'
|
||||
X:; ./shx
|
||||
|
||||
sh:
|
||||
X<&$fd ok
|
||||
nlbq Mon Aug 3 02:45:00 EDT 1992
|
||||
bang geoff
|
||||
quote 712824302
|
||||
setbq defmsgid=<1992Aug3.024502.6176@host>
|
||||
bgwait sleep done... wait 6187
|
||||
|
||||
|
||||
bash:
|
||||
X<&$fd ok
|
||||
nlbq Mon Aug 3 02:45:09 EDT 1992
|
||||
bang geoff
|
||||
quote 712824311
|
||||
setbq defmsgid=<1992Aug3.024512.6212@host>
|
||||
bgwait sleep done... wait 6223
|
||||
|
||||
|
||||
ash:
|
||||
X<&$fd shx1: 4: Syntax error: Bad fd number
|
||||
nlbq Mon Aug 3 02:45:19 EDT 1992
|
||||
bang geoff
|
||||
quote getdate: `"now"' not a valid date
|
||||
|
||||
setbq defmsgid=<1992Aug3.` echo 024521
|
||||
bgwait sleep done... wait 6241
|
||||
|
||||
|
||||
ksh:
|
||||
X<&$fd ok
|
||||
nlbq ./shx: 6248 Memory fault - core dumped
|
||||
bang geoff
|
||||
quote getdate: `"now"' not a valid date
|
||||
|
||||
setbq defmsgid=<1992Aug3.024530.6257@host>
|
||||
bgwait no such job: 6265
|
||||
wait 6265
|
||||
sleep done...
|
||||
|
||||
zsh:
|
||||
X<&$fd ok
|
||||
nlbq Mon Aug 3 02:45:36 EDT 1992
|
||||
bang shx3: event not found: /s/ [4]
|
||||
quote 712824337
|
||||
setbq defmsgid=<..6290@host>
|
||||
bgwait shx7: unmatched " [9]
|
||||
sleep done...
|
||||
X:;
|
||||
!
|
||||
echo shx 1>&2
|
||||
sed 's/^X//' >shx <<'!'
|
||||
X#! /bin/sh
|
||||
for cmd in sh bash ash ksh zsh
|
||||
do
|
||||
X echo
|
||||
X echo $cmd:
|
||||
X for demo in shx?
|
||||
X do
|
||||
X $cmd $demo
|
||||
X done
|
||||
done
|
||||
!
|
||||
echo shx1 1>&2
|
||||
sed 's/^X//' >shx1 <<'!'
|
||||
X# ash fails this one
|
||||
echo -n '<&$fd '
|
||||
fd=3
|
||||
echo ok <&$fd
|
||||
!
|
||||
echo shx2 1>&2
|
||||
sed 's/^X//' >shx2 <<'!'
|
||||
X# pd ksh fails this one
|
||||
echo -n "nlbq "
|
||||
date=`
|
||||
date`
|
||||
echo "$date"
|
||||
!
|
||||
echo shx3 1>&2
|
||||
sed 's/^X//' >shx3 <<'!'
|
||||
X# zsh fails this one
|
||||
echo -n 'bang '
|
||||
echo 'geoff tty?? Aug 3 02:35' |
|
||||
X sed -e 's/[ ].*//' -e '/!/s/^.*!//'
|
||||
!
|
||||
echo shx4 1>&2
|
||||
sed 's/^X//' >shx4 <<'!'
|
||||
X# ash, pd ksh fail this one
|
||||
echo -n "quote "
|
||||
expiry="now"
|
||||
timet="` getdate \"$expiry\" `"
|
||||
echo "$timet"
|
||||
!
|
||||
echo shx5 1>&2
|
||||
sed 's/^X//' >shx5 <<'!'
|
||||
X# ash, zsh fail this one
|
||||
echo -n "setbq "
|
||||
host=host
|
||||
date="`date`"
|
||||
echo defmsgid="`set $date; echo \<$6$2$3.\` echo $4 | tr -d : \`.$$@$host\>`"
|
||||
!
|
||||
echo shx7 1>&2
|
||||
sed 's/^X//' >shx7 <<'!'
|
||||
X# pd ksh and zsh fail this one
|
||||
echo -n "bgwait "
|
||||
X(
|
||||
X sleep 2
|
||||
X echo -n "sleep done... "
|
||||
X) &
|
||||
waitcmd="wait $!"
|
||||
eval $waitcmd
|
||||
echo "$waitcmd"
|
||||
!
|
||||
echo shx8 1>&2
|
||||
sed 's/^X//' >shx8 <<'!'
|
||||
X# in case gcx7 is really breaks this shell
|
||||
sleep 3
|
||||
echo
|
||||
!
|
||||
exit 0
|
||||
@@ -1,9 +0,0 @@
|
||||
all: getdate
|
||||
|
||||
getdate.c: getdate.y
|
||||
yacc getdate.y
|
||||
mv y.tab.c getdate.c
|
||||
|
||||
getdate: getdate.c
|
||||
$(CC) -o $@ getdate.c
|
||||
rm -f getdate.c getdate.o
|
||||
@@ -1,553 +0,0 @@
|
||||
%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
|
||||
%{
|
||||
/* Steven M. Bellovin (unc!smb) */
|
||||
/* Dept. of Computer Science */
|
||||
/* University of North Carolina at Chapel Hill */
|
||||
/* @(#)getdate.y 2.13 9/16/86 */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#define timezone tmzn /* ugly hack for obscure name clash */
|
||||
#include <sys/timeb.h>
|
||||
|
||||
#define daysec (24L*60L*60L)
|
||||
|
||||
static int timeflag, zoneflag, dateflag, dayflag, relflag;
|
||||
static time_t relsec, relmonth;
|
||||
static int hh, mm, ss, merid, daylight;
|
||||
static int dayord, dayreq;
|
||||
static int month, day, year;
|
||||
static int ourzone;
|
||||
|
||||
#define AM 1
|
||||
#define PM 2
|
||||
#define DAYLIGHT 1
|
||||
#define STANDARD 2
|
||||
#define MAYBE 3
|
||||
%}
|
||||
|
||||
%%
|
||||
timedate: /* empty */
|
||||
| timedate item;
|
||||
|
||||
item: tspec =
|
||||
{timeflag++;}
|
||||
| zone =
|
||||
{zoneflag++;}
|
||||
| dtspec =
|
||||
{dateflag++;}
|
||||
| dyspec =
|
||||
{dayflag++;}
|
||||
| rspec =
|
||||
{relflag++;}
|
||||
| nspec;
|
||||
|
||||
nspec: NUMBER =
|
||||
{if (timeflag && dateflag && !relflag) year = $1;
|
||||
else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
|
||||
|
||||
tspec: NUMBER MERIDIAN =
|
||||
{hh = $1; mm = 0; ss = 0; merid = $2;}
|
||||
| NUMBER ':' NUMBER =
|
||||
{hh = $1; mm = $3; merid = 24;}
|
||||
| NUMBER ':' NUMBER MERIDIAN =
|
||||
{hh = $1; mm = $3; merid = $4;}
|
||||
| NUMBER ':' NUMBER NUMBER =
|
||||
{hh = $1; mm = $3; merid = 24;
|
||||
daylight = STANDARD; ourzone = $4%100 + 60*$4/100;}
|
||||
| NUMBER ':' NUMBER ':' NUMBER =
|
||||
{hh = $1; mm = $3; ss = $5; merid = 24;}
|
||||
| NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
|
||||
{hh = $1; mm = $3; ss = $5; merid = $6;}
|
||||
| NUMBER ':' NUMBER ':' NUMBER NUMBER =
|
||||
{hh = $1; mm = $3; ss = $5; merid = 24;
|
||||
daylight = STANDARD; ourzone = $6%100 + 60*$6/100;};
|
||||
|
||||
zone: ZONE =
|
||||
{ourzone = $1; daylight = STANDARD;}
|
||||
| DAYZONE =
|
||||
{ourzone = $1; daylight = DAYLIGHT;};
|
||||
|
||||
dyspec: DAY =
|
||||
{dayord = 1; dayreq = $1;}
|
||||
| DAY ',' =
|
||||
{dayord = 1; dayreq = $1;}
|
||||
| NUMBER DAY =
|
||||
{dayord = $1; dayreq = $2;};
|
||||
|
||||
dtspec: NUMBER '/' NUMBER =
|
||||
{month = $1; day = $3;}
|
||||
| NUMBER '/' NUMBER '/' NUMBER =
|
||||
{month = $1; day = $3; year = $5;}
|
||||
| MONTH NUMBER =
|
||||
{month = $1; day = $2;}
|
||||
| MONTH NUMBER ',' NUMBER =
|
||||
{month = $1; day = $2; year = $4;}
|
||||
| NUMBER MONTH =
|
||||
{month = $2; day = $1;}
|
||||
| NUMBER MONTH NUMBER =
|
||||
{month = $2; day = $1; year = $3;};
|
||||
|
||||
|
||||
rspec: NUMBER UNIT =
|
||||
{relsec += 60L * $1 * $2;}
|
||||
| NUMBER MUNIT =
|
||||
{relmonth += $1 * $2;}
|
||||
| NUMBER SUNIT =
|
||||
{relsec += $1;}
|
||||
| UNIT =
|
||||
{relsec += 60L * $1;}
|
||||
| MUNIT =
|
||||
{relmonth += $1;}
|
||||
| SUNIT =
|
||||
{relsec++;}
|
||||
| rspec AGO =
|
||||
{relsec = -relsec; relmonth = -relmonth;};
|
||||
%%
|
||||
|
||||
static int mdays[12] =
|
||||
{31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
#define epoch 1970
|
||||
|
||||
extern struct tm *localtime();
|
||||
|
||||
static time_t
|
||||
dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
|
||||
int mm, dd, yy, h, m, s, mer, zone, dayflag;
|
||||
{
|
||||
time_t tod, jdate;
|
||||
register int i;
|
||||
time_t timeconv();
|
||||
|
||||
if (yy < 0) yy = -yy;
|
||||
if (yy < 100) yy += 1900;
|
||||
mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
|
||||
if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
|
||||
dd < 1 || dd > mdays[--mm]) return (-1);
|
||||
jdate = dd-1;
|
||||
for (i=0; i<mm; i++) jdate += mdays[i];
|
||||
for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
|
||||
jdate *= daysec;
|
||||
jdate += zone * 60L;
|
||||
if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
|
||||
jdate += tod;
|
||||
if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
|
||||
jdate += -1*60*60;
|
||||
return (jdate);
|
||||
}
|
||||
|
||||
static time_t
|
||||
dayconv(ord, day, now)
|
||||
int ord, day; time_t now;
|
||||
{
|
||||
register struct tm *loctime;
|
||||
time_t tod;
|
||||
time_t daylcorr();
|
||||
|
||||
tod = now;
|
||||
loctime = localtime(&tod);
|
||||
tod += daysec * ((day - loctime->tm_wday + 7) % 7);
|
||||
tod += 7*daysec*(ord<=0?ord:ord-1);
|
||||
return daylcorr(tod, now);
|
||||
}
|
||||
|
||||
static time_t
|
||||
timeconv(hh, mm, ss, mer)
|
||||
register int hh, mm, ss, mer;
|
||||
{
|
||||
if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
|
||||
switch (mer) {
|
||||
case AM: if (hh < 1 || hh > 12) return(-1);
|
||||
return (60L * ((hh%12)*60L + mm)+ss);
|
||||
case PM: if (hh < 1 || hh > 12) return(-1);
|
||||
return (60L * ((hh%12 +12)*60L + mm)+ss);
|
||||
case 24: if (hh < 0 || hh > 23) return (-1);
|
||||
return (60L * (hh*60L + mm)+ss);
|
||||
default: return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
static time_t
|
||||
monthadd(sdate, relmonth)
|
||||
time_t sdate, relmonth;
|
||||
{
|
||||
struct tm *ltime;
|
||||
time_t dateconv();
|
||||
time_t daylcorr();
|
||||
int mm, yy;
|
||||
|
||||
if (relmonth == 0) return 0;
|
||||
ltime = localtime(&sdate);
|
||||
mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
|
||||
yy = mm/12;
|
||||
mm = mm%12 + 1;
|
||||
return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
|
||||
ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
|
||||
}
|
||||
|
||||
static time_t
|
||||
daylcorr(future, now)
|
||||
time_t future, now;
|
||||
{
|
||||
int fdayl, nowdayl;
|
||||
|
||||
nowdayl = (localtime(&now)->tm_hour+1) % 24;
|
||||
fdayl = (localtime(&future)->tm_hour+1) % 24;
|
||||
return (future-now) + 60L*60L*(nowdayl-fdayl);
|
||||
}
|
||||
|
||||
static char *lptr;
|
||||
|
||||
yylex()
|
||||
{
|
||||
extern int yylval;
|
||||
int sign;
|
||||
register char c;
|
||||
register char *p;
|
||||
char idbuf[20];
|
||||
int pcnt;
|
||||
|
||||
for (;;) {
|
||||
while (isspace(*lptr)) lptr++;
|
||||
|
||||
if (isdigit(c = *lptr) || c == '-' || c == '+') {
|
||||
if (c== '-' || c == '+') {
|
||||
if (c=='-') sign = -1;
|
||||
else sign = 1;
|
||||
if (!isdigit(*++lptr)) {
|
||||
/* yylval = sign; return (NUMBER); */
|
||||
return yylex(); /* skip the '-' sign */
|
||||
}
|
||||
} else sign = 1;
|
||||
yylval = 0;
|
||||
while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
|
||||
yylval *= sign;
|
||||
lptr--;
|
||||
return (NUMBER);
|
||||
|
||||
} else if (isalpha(c)) {
|
||||
p = idbuf;
|
||||
while (isalpha(c = *lptr++) || c=='.')
|
||||
if (p < &idbuf[sizeof(idbuf)-1])
|
||||
*p++ = c;
|
||||
*p = '\0';
|
||||
lptr--;
|
||||
return (lookup(idbuf));
|
||||
}
|
||||
|
||||
else if (c == '(') {
|
||||
pcnt = 0;
|
||||
do {
|
||||
c = *lptr++;
|
||||
if (c == '\0') return(c);
|
||||
else if (c == '(') pcnt++;
|
||||
else if (c == ')') pcnt--;
|
||||
} while (pcnt > 0);
|
||||
}
|
||||
|
||||
else return (*lptr++);
|
||||
}
|
||||
}
|
||||
|
||||
struct table {
|
||||
char *name;
|
||||
int type, value;
|
||||
};
|
||||
|
||||
static struct table mdtab[] = {
|
||||
{"January", MONTH, 1},
|
||||
{"February", MONTH, 2},
|
||||
{"March", MONTH, 3},
|
||||
{"April", MONTH, 4},
|
||||
{"May", MONTH, 5},
|
||||
{"June", MONTH, 6},
|
||||
{"July", MONTH, 7},
|
||||
{"August", MONTH, 8},
|
||||
{"September", MONTH, 9},
|
||||
{"Sept", MONTH, 9},
|
||||
{"October", MONTH, 10},
|
||||
{"November", MONTH, 11},
|
||||
{"December", MONTH, 12},
|
||||
|
||||
{"Sunday", DAY, 0},
|
||||
{"Monday", DAY, 1},
|
||||
{"Tuesday", DAY, 2},
|
||||
{"Tues", DAY, 2},
|
||||
{"Wednesday", DAY, 3},
|
||||
{"Wednes", DAY, 3},
|
||||
{"Thursday", DAY, 4},
|
||||
{"Thur", DAY, 4},
|
||||
{"Thurs", DAY, 4},
|
||||
{"Friday", DAY, 5},
|
||||
{"Saturday", DAY, 6},
|
||||
{0, 0, 0}};
|
||||
|
||||
#define HRS *60
|
||||
#define HALFHR 30
|
||||
static struct table mztab[] = {
|
||||
{"a.m.", MERIDIAN, AM},
|
||||
{"am", MERIDIAN, AM},
|
||||
{"p.m.", MERIDIAN, PM},
|
||||
{"pm", MERIDIAN, PM},
|
||||
{"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */
|
||||
{"n.s.t.", ZONE, 3 HRS + HALFHR},
|
||||
{"ast", ZONE, 4 HRS}, /* Atlantic */
|
||||
{"a.s.t.", ZONE, 4 HRS},
|
||||
{"adt", DAYZONE, 4 HRS},
|
||||
{"a.d.t.", DAYZONE, 4 HRS},
|
||||
{"est", ZONE, 5 HRS}, /* Eastern */
|
||||
{"e.s.t.", ZONE, 5 HRS},
|
||||
{"edt", DAYZONE, 5 HRS},
|
||||
{"e.d.t.", DAYZONE, 5 HRS},
|
||||
{"cst", ZONE, 6 HRS}, /* Central */
|
||||
{"c.s.t.", ZONE, 6 HRS},
|
||||
{"cdt", DAYZONE, 6 HRS},
|
||||
{"c.d.t.", DAYZONE, 6 HRS},
|
||||
{"mst", ZONE, 7 HRS}, /* Mountain */
|
||||
{"m.s.t.", ZONE, 7 HRS},
|
||||
{"mdt", DAYZONE, 7 HRS},
|
||||
{"m.d.t.", DAYZONE, 7 HRS},
|
||||
{"pst", ZONE, 8 HRS}, /* Pacific */
|
||||
{"p.s.t.", ZONE, 8 HRS},
|
||||
{"pdt", DAYZONE, 8 HRS},
|
||||
{"p.d.t.", DAYZONE, 8 HRS},
|
||||
{"yst", ZONE, 9 HRS}, /* Yukon */
|
||||
{"y.s.t.", ZONE, 9 HRS},
|
||||
{"ydt", DAYZONE, 9 HRS},
|
||||
{"y.d.t.", DAYZONE, 9 HRS},
|
||||
{"hst", ZONE, 10 HRS}, /* Hawaii */
|
||||
{"h.s.t.", ZONE, 10 HRS},
|
||||
{"hdt", DAYZONE, 10 HRS},
|
||||
{"h.d.t.", DAYZONE, 10 HRS},
|
||||
|
||||
{"gmt", ZONE, 0 HRS},
|
||||
{"g.m.t.", ZONE, 0 HRS},
|
||||
{"ut", ZONE, 0 HRS},
|
||||
{"u.t.", ZONE, 0 HRS},
|
||||
{"bst", DAYZONE, 0 HRS}, /* British Summer Time */
|
||||
{"b.s.t.", DAYZONE, 0 HRS},
|
||||
{"eet", ZONE, 0 HRS}, /* European Eastern Time */
|
||||
{"e.e.t.", ZONE, 0 HRS},
|
||||
{"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */
|
||||
{"e.e.s.t.", DAYZONE, 0 HRS},
|
||||
{"met", ZONE, -1 HRS}, /* Middle European Time */
|
||||
{"m.e.t.", ZONE, -1 HRS},
|
||||
{"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */
|
||||
{"m.e.s.t.", DAYZONE, -1 HRS},
|
||||
{"wet", ZONE, -2 HRS }, /* Western European Time */
|
||||
{"w.e.t.", ZONE, -2 HRS },
|
||||
{"west", DAYZONE, -2 HRS}, /* Western European Summer Time */
|
||||
{"w.e.s.t.", DAYZONE, -2 HRS},
|
||||
|
||||
{"jst", ZONE, -9 HRS}, /* Japan Standard Time */
|
||||
{"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */
|
||||
/* No daylight savings time */
|
||||
|
||||
{"aest", ZONE, -10 HRS}, /* Australian Eastern Time */
|
||||
{"a.e.s.t.", ZONE, -10 HRS},
|
||||
{"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */
|
||||
{"a.e.s.s.t.", DAYZONE, -10 HRS},
|
||||
{"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */
|
||||
{"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
|
||||
{"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */
|
||||
{"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
|
||||
{"awst", ZONE, -8 HRS}, /* Australian Western Time */
|
||||
{"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */
|
||||
{0, 0, 0}};
|
||||
|
||||
static struct table unittb[] = {
|
||||
{"year", MUNIT, 12},
|
||||
{"month", MUNIT, 1},
|
||||
{"fortnight", UNIT, 14*24*60},
|
||||
{"week", UNIT, 7*24*60},
|
||||
{"day", UNIT, 1*24*60},
|
||||
{"hour", UNIT, 60},
|
||||
{"minute", UNIT, 1},
|
||||
{"min", UNIT, 1},
|
||||
{"second", SUNIT, 1},
|
||||
{"sec", SUNIT, 1},
|
||||
{0, 0, 0}};
|
||||
|
||||
static struct table othertb[] = {
|
||||
{"tomorrow", UNIT, 1*24*60},
|
||||
{"yesterday", UNIT, -1*24*60},
|
||||
{"today", UNIT, 0},
|
||||
{"now", UNIT, 0},
|
||||
{"last", NUMBER, -1},
|
||||
{"this", UNIT, 0},
|
||||
{"next", NUMBER, 2},
|
||||
{"first", NUMBER, 1},
|
||||
/* {"second", NUMBER, 2}, */
|
||||
{"third", NUMBER, 3},
|
||||
{"fourth", NUMBER, 4},
|
||||
{"fifth", NUMBER, 5},
|
||||
{"sixth", NUMBER, 6},
|
||||
{"seventh", NUMBER, 7},
|
||||
{"eigth", NUMBER, 8},
|
||||
{"ninth", NUMBER, 9},
|
||||
{"tenth", NUMBER, 10},
|
||||
{"eleventh", NUMBER, 11},
|
||||
{"twelfth", NUMBER, 12},
|
||||
{"ago", AGO, 1},
|
||||
{0, 0, 0}};
|
||||
|
||||
static struct table milzone[] = {
|
||||
{"a", ZONE, 1 HRS},
|
||||
{"b", ZONE, 2 HRS},
|
||||
{"c", ZONE, 3 HRS},
|
||||
{"d", ZONE, 4 HRS},
|
||||
{"e", ZONE, 5 HRS},
|
||||
{"f", ZONE, 6 HRS},
|
||||
{"g", ZONE, 7 HRS},
|
||||
{"h", ZONE, 8 HRS},
|
||||
{"i", ZONE, 9 HRS},
|
||||
{"k", ZONE, 10 HRS},
|
||||
{"l", ZONE, 11 HRS},
|
||||
{"m", ZONE, 12 HRS},
|
||||
{"n", ZONE, -1 HRS},
|
||||
{"o", ZONE, -2 HRS},
|
||||
{"p", ZONE, -3 HRS},
|
||||
{"q", ZONE, -4 HRS},
|
||||
{"r", ZONE, -5 HRS},
|
||||
{"s", ZONE, -6 HRS},
|
||||
{"t", ZONE, -7 HRS},
|
||||
{"u", ZONE, -8 HRS},
|
||||
{"v", ZONE, -9 HRS},
|
||||
{"w", ZONE, -10 HRS},
|
||||
{"x", ZONE, -11 HRS},
|
||||
{"y", ZONE, -12 HRS},
|
||||
{"z", ZONE, 0 HRS},
|
||||
{0, 0, 0}};
|
||||
|
||||
static
|
||||
lookup(id)
|
||||
char *id;
|
||||
{
|
||||
#define gotit (yylval=i->value, i->type)
|
||||
#define getid for(j=idvar, k=id; *j++ = *k++; )
|
||||
|
||||
char idvar[20];
|
||||
register char *j, *k;
|
||||
register struct table *i;
|
||||
int abbrev;
|
||||
|
||||
getid;
|
||||
if (strlen(idvar) == 3) abbrev = 1;
|
||||
else if (strlen(idvar) == 4 && idvar[3] == '.') {
|
||||
abbrev = 1;
|
||||
idvar[3] = '\0';
|
||||
}
|
||||
else abbrev = 0;
|
||||
|
||||
if (islower(*idvar)) *idvar = toupper(*idvar);
|
||||
|
||||
for (i = mdtab; i->name; i++) {
|
||||
k = idvar;
|
||||
for (j = i->name; *j++ == *k++;) {
|
||||
if (abbrev && j==i->name+3) return gotit;
|
||||
if (j[-1] == 0) return gotit;
|
||||
}
|
||||
}
|
||||
|
||||
getid;
|
||||
for (i = mztab; i->name; i++)
|
||||
if (strcmp(i->name, idvar) == 0) return gotit;
|
||||
|
||||
for (j = idvar; *j; j++)
|
||||
if (isupper(*j)) *j = tolower(*j);
|
||||
for (i=mztab; i->name; i++)
|
||||
if (strcmp(i->name, idvar) == 0) return gotit;
|
||||
|
||||
getid;
|
||||
for (i=unittb; i->name; i++)
|
||||
if (strcmp(i->name, idvar) == 0) return gotit;
|
||||
|
||||
if (idvar[strlen(idvar)-1] == 's')
|
||||
idvar[strlen(idvar)-1] = '\0';
|
||||
for (i=unittb; i->name; i++)
|
||||
if (strcmp(i->name, idvar) == 0) return gotit;
|
||||
|
||||
getid;
|
||||
for (i = othertb; i->name; i++)
|
||||
if (strcmp(i->name, idvar) == 0) return gotit;
|
||||
|
||||
getid;
|
||||
if (strlen(idvar) == 1 && isalpha(*idvar)) {
|
||||
if (isupper(*idvar)) *idvar = tolower(*idvar);
|
||||
for (i = milzone; i->name; i++)
|
||||
if (strcmp(i->name, idvar) == 0) return gotit;
|
||||
}
|
||||
|
||||
return(ID);
|
||||
}
|
||||
|
||||
time_t
|
||||
getdate(p, now)
|
||||
char *p;
|
||||
struct timeb *now;
|
||||
{
|
||||
#define mcheck(f) if (f>1) err++
|
||||
time_t monthadd();
|
||||
int err;
|
||||
struct tm *lt;
|
||||
struct timeb ftz;
|
||||
|
||||
time_t sdate, tod;
|
||||
|
||||
lptr = p;
|
||||
if (now == ((struct timeb *) NULL)) {
|
||||
now = &ftz;
|
||||
ftime(&ftz);
|
||||
}
|
||||
lt = localtime(&now->time);
|
||||
year = lt->tm_year;
|
||||
month = lt->tm_mon+1;
|
||||
day = lt->tm_mday;
|
||||
relsec = 0; relmonth = 0;
|
||||
timeflag=zoneflag=dateflag=dayflag=relflag=0;
|
||||
ourzone = now->timezone;
|
||||
daylight = MAYBE;
|
||||
hh = mm = ss = 0;
|
||||
merid = 24;
|
||||
|
||||
if (err = yyparse()) return (-1);
|
||||
|
||||
mcheck(timeflag);
|
||||
mcheck(zoneflag);
|
||||
mcheck(dateflag);
|
||||
mcheck(dayflag);
|
||||
|
||||
if (err) return (-1);
|
||||
if (dateflag || timeflag || dayflag) {
|
||||
sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight);
|
||||
if (sdate < 0) return -1;
|
||||
}
|
||||
else {
|
||||
sdate = now->time;
|
||||
if (relflag == 0)
|
||||
sdate -= (lt->tm_sec + lt->tm_min*60 +
|
||||
lt->tm_hour*(60L*60L));
|
||||
}
|
||||
|
||||
sdate += relsec;
|
||||
sdate += monthadd(sdate, relmonth);
|
||||
|
||||
if (dayflag && !dateflag) {
|
||||
tod = dayconv(dayord, dayreq, sdate);
|
||||
sdate += tod;
|
||||
}
|
||||
|
||||
return sdate;
|
||||
}
|
||||
|
||||
yyerror(s) char *s;
|
||||
{}
|
||||
|
||||
main(c, v)
|
||||
int c;
|
||||
char **v;
|
||||
{
|
||||
printf("%d\n", getdate(v[1], (struct timeb *)0));
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
if ksh -c 'echo ""' >/dev/null 2>&1; then
|
||||
ksh=ksh
|
||||
fi
|
||||
|
||||
for cmd in sh ../../bash $ksh
|
||||
do
|
||||
echo
|
||||
echo $cmd:
|
||||
for demo in shx[0-9]
|
||||
do
|
||||
$cmd $demo
|
||||
done
|
||||
done
|
||||
@@ -1,4 +0,0 @@
|
||||
# ash fails this one
|
||||
echo -n '<&$fd '
|
||||
fd=3
|
||||
echo ok <&$fd
|
||||
@@ -1,5 +0,0 @@
|
||||
# pd ksh fails this one
|
||||
echo -n "nlbq "
|
||||
date=`
|
||||
date`
|
||||
echo "$date"
|
||||
@@ -1,4 +0,0 @@
|
||||
# zsh fails this one
|
||||
echo -n 'bang '
|
||||
echo 'geoff tty?? Aug 3 02:35' |
|
||||
sed -e 's/[ ].*//' -e '/!/s/^.*!//'
|
||||
@@ -1,5 +0,0 @@
|
||||
# ash, pd ksh fail this one
|
||||
echo -n "quote "
|
||||
expiry="now"
|
||||
timet="` getdate \"$expiry\" `"
|
||||
echo "$timet"
|
||||
@@ -1,5 +0,0 @@
|
||||
# ash, zsh fail this one
|
||||
echo -n "setbq "
|
||||
host=host
|
||||
date="`date`"
|
||||
echo defmsgid="`set $date; echo \<$6$2$3.\` echo $4 | tr -d : \`.$$@$host\>`"
|
||||
@@ -1,9 +0,0 @@
|
||||
# pd ksh and zsh fail this one
|
||||
echo -n "bgwait "
|
||||
(
|
||||
sleep 2
|
||||
echo -n "sleep done... "
|
||||
) &
|
||||
waitcmd="wait $!"
|
||||
eval $waitcmd
|
||||
echo "$waitcmd"
|
||||
@@ -1,3 +0,0 @@
|
||||
# in case gcx7 is really breaks this shell
|
||||
sleep 3
|
||||
echo
|
||||
@@ -1,13 +0,0 @@
|
||||
#
|
||||
# show that IFS is only applied to the result of expansions
|
||||
#
|
||||
${THIS_SH} ifs-1.test > /tmp/xx
|
||||
diff /tmp/xx ./ifs-1.right
|
||||
|
||||
${THIS_SH} ifs-2.test > /tmp/xx
|
||||
diff /tmp/xx ./ifs-2.right
|
||||
|
||||
${THIS_SH} ifs-3.test > /tmp/xx
|
||||
diff /tmp/xx ./ifs-3.right
|
||||
|
||||
rm -f /tmp/xx
|
||||
@@ -1,2 +0,0 @@
|
||||
cat ./input-line-2.sh | ${THIS_SH} > /tmp/xx
|
||||
diff /tmp/xx input.right && rm -f /tmp/xx
|
||||
@@ -1,2 +0,0 @@
|
||||
${THIS_SH} ./minus-e > /tmp/xx
|
||||
diff /tmp/xx minus-e.right && rm -f /tmp/xx
|
||||
@@ -1 +0,0 @@
|
||||
../../bash ./redir-t2.sh < /etc/passwd
|
||||
@@ -1,9 +0,0 @@
|
||||
echo before trap
|
||||
trap 'echo caught sigint' 2
|
||||
echo after trap
|
||||
|
||||
for i in 1 2 3
|
||||
do
|
||||
echo $i
|
||||
sleep 5
|
||||
done
|
||||
@@ -1,7 +0,0 @@
|
||||
echo before loop
|
||||
|
||||
for i in 1 2 3
|
||||
do
|
||||
echo $i
|
||||
sleep 5
|
||||
done
|
||||
@@ -1,11 +0,0 @@
|
||||
sleep 5 &
|
||||
sleep 5 &
|
||||
sleep 5 &
|
||||
|
||||
echo wait 1
|
||||
wait
|
||||
|
||||
echo wait 2
|
||||
wait
|
||||
|
||||
exit
|
||||
@@ -1,13 +0,0 @@
|
||||
trap 'echo sigint' 2
|
||||
|
||||
sleep 5 &
|
||||
sleep 5 &
|
||||
sleep 5 &
|
||||
|
||||
echo wait 1
|
||||
wait
|
||||
|
||||
echo wait 2
|
||||
wait
|
||||
|
||||
exit
|
||||
@@ -1,9 +0,0 @@
|
||||
touch .file
|
||||
while set -e ; test -r .file ; do
|
||||
echo -n "stop loop? "
|
||||
read reply
|
||||
case "$reply" in
|
||||
y*) rm .file non-dash-file ;;
|
||||
esac
|
||||
set +e
|
||||
done
|
||||
@@ -1,11 +0,0 @@
|
||||
touch .file
|
||||
set -e
|
||||
while set +e ; test -r .file ; do
|
||||
echo -n "stop loop? [yes to quit] "
|
||||
read reply
|
||||
if [ "$reply" = yes ] ; then
|
||||
rm .file non-dash-file
|
||||
fi
|
||||
set -e
|
||||
done
|
||||
rm -f .file
|
||||
@@ -1,15 +0,0 @@
|
||||
# these will work only if test.c has been compiled with -DPATTERN_MATCHING
|
||||
# to get =~ and !~
|
||||
|
||||
[ a =\~ a ] && echo OK || echo BAD
|
||||
[ a !~ b ] && echo OK || echo BAD
|
||||
|
||||
[ a =\~ \* ] && echo OK || echo BAD
|
||||
[ a =\~ \? ] && echo OK || echo BAD
|
||||
[ abc !~ \? ] && echo OK || echo BAD
|
||||
|
||||
[ '' =\~ \* ] && echo OK || echo BAD
|
||||
[ '' !~ \?\* ] && echo OK || echo BAD
|
||||
|
||||
[ a =\~ \[abc] ] && echo OK || echo BAD
|
||||
[ x !~ \[abc] ] && echo OK || echo BAD
|
||||
@@ -1,50 +0,0 @@
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
: ${THIS_SH:=./bash}
|
||||
|
||||
printf "time -c : :\n"
|
||||
time ${THIS_SH} -c :
|
||||
|
||||
printf "time /dev/null:\n"
|
||||
time ${THIS_SH} /dev/null
|
||||
|
||||
printf "\nPOSIX: time -p /dev/null:\n"
|
||||
time -p ${THIS_SH} /dev/null
|
||||
|
||||
printf "\nBSD time /dev/null:\n"
|
||||
TIMEFORMAT=$'\t%1R real\t%1U user\t%1S sys'
|
||||
time ${THIS_SH} /dev/null
|
||||
|
||||
printf "\nSYSV time /dev/null:\n"
|
||||
TIMEFORMAT=$'\nreal\t%1R\nuser\t%1U\nsys\t%1S'
|
||||
time ${THIS_SH} /dev/null
|
||||
|
||||
printf "\nksh time /dev/null:\n"
|
||||
TIMEFORMAT=$'\nreal\t%2lR\nuser\t%2lU\nsys\t%2lS'
|
||||
time ${THIS_SH} < /dev/null
|
||||
|
||||
time (:)
|
||||
(time :)
|
||||
|
||||
times -x
|
||||
|
||||
printf "\ntimes:\n"
|
||||
times
|
||||
echo
|
||||
times --
|
||||
|
||||
printf "\ntime standalone:\n"
|
||||
{ time ; echo after; } |& wc -l
|
||||
|
||||
exit 0
|
||||
@@ -1,25 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
i=0
|
||||
while [ $i -lt $1 ]
|
||||
do
|
||||
/bin/sh -c "sleep 4; exit 0" &
|
||||
rv=$?
|
||||
pid=$!
|
||||
eval bg_pid_$i=$pid
|
||||
echo $$: Job $i: pid is $pid rv=$rv
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
|
||||
|
||||
i=0
|
||||
while [ $i -lt $1 ]
|
||||
do
|
||||
eval wpid=\$bg_pid_$i
|
||||
echo Waiting for job $i '('pid $wpid')'
|
||||
wait $wpid
|
||||
rv=$?
|
||||
echo Return value is $rv
|
||||
i=$((i + 1))
|
||||
done
|
||||
Reference in New Issue
Block a user