--- ../bash-5.1.8-ori/builtins/read.def 2020-06-05 19:18:28.000000000 +0200 +++ builtins/read.def 2021-10-23 21:23:37.067915781 +0200 @@ -22,7 +22,7 @@ $BUILTIN read $FUNCTION read_builtin -$SHORT_DOC read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] +$SHORT_DOC read [-eErs] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] Read a line from the standard input and split it into fields. Reads a single line from the standard input, or from file descriptor FD @@ -40,6 +40,7 @@ -d delim continue until the first character of DELIM is read, rather than newline -e use Readline to obtain the line + -E return text between last newline and EOF -i text use TEXT as the initial text for Readline -n nchars return after reading NCHARS characters rather than waiting for a newline, but honor a delimiter if fewer than @@ -179,7 +180,7 @@ int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag; volatile int i; int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; - int raw, edit, nchars, silent, have_timeout, ignore_delim, fd; + int raw, edit, eof_terminates_line, nchars, silent, have_timeout, ignore_delim, fd; int lastsig, t_errno; int mb_cur_max; unsigned int tmsec, tmusec; @@ -209,6 +210,7 @@ USE_VAR(input_is_pipe); /* USE_VAR(raw); */ USE_VAR(edit); + USE_VAR(eof_terminates_line); USE_VAR(tmsec); USE_VAR(tmusec); USE_VAR(nchars); @@ -229,6 +231,7 @@ i = 0; /* Index into the string that we are reading. */ raw = edit = 0; /* Not reading raw input by default. */ + eof_terminates_line = 0; silent = 0; arrayname = prompt = (char *)NULL; fd = 0; /* file descriptor to read from */ @@ -245,7 +248,7 @@ ignore_delim = nflag = 0; reset_internal_getopt (); - while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:N:")) != -1) + while ((opt = internal_getopt (list, "eErsa:d:i:n:p:t:u:N:")) != -1) { switch (opt) { @@ -263,6 +266,9 @@ edit = 1; #endif break; + case 'E': + eof_terminates_line = 1; + break; case 'i': #if defined (READLINE) itext = list_optarg; @@ -788,7 +794,14 @@ discard_unwind_frame ("read_builtin"); - retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; + if (!eof_terminates_line) + { + retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; + } + else + { + retval = eof && strlen (input_string) == 0 ? EXECUTION_FAILURE : EXECUTION_SUCCESS; + } assign_vars: