diff --git a/src/builtin_read.cpp b/src/builtin_read.cpp index 173462918..052678143 100644 --- a/src/builtin_read.cpp +++ b/src/builtin_read.cpp @@ -608,6 +608,14 @@ int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) { wcstring substr; loc = wcstring_tok(buff, (vars_left() > 1) ? opts.delimiter : wcstring(), loc); if (loc.first != wcstring::npos) { + if (vars_left() == 1) { // Discard trailing delimiters, see #6406 + loc.first = + std::find_if(buff.begin() + loc.first, buff.end(), + [&opts](wchar_t c) { + return opts.delimiter.find(c) == wcstring::npos; + }) - + buff.begin(); + } substr = wcstring(buff, loc.first, loc.second); } vars.set_one(*var_ptr++, opts.place, substr); diff --git a/tests/checks/read.fish b/tests/checks/read.fish index fee0bb3c6..210f6022c 100644 --- a/tests/checks/read.fish +++ b/tests/checks/read.fish @@ -12,3 +12,11 @@ set -l # CHECK: a 'afoo barb' # CHECK: b # CHECK: c + +echo "a b b" | read a b; string escape $a $b +# CHECK: a +# CHECK: 'b b' + +echo 'a<><>b<>b' | read -d '<>' a b; printf %s\n $a $b +# CHECK: a +# CHECK: <>b<>b diff --git a/tests/read.out b/tests/read.out index f29e2e1b9..177985ea2 100644 --- a/tests/read.out +++ b/tests/read.out @@ -27,7 +27,7 @@ two 1 '' 1 '' 1 '' 1 'test' 1 '' 1 '' -1 'foo' 1 'bar' 1 ' baz' +1 'foo' 1 'bar' 1 'baz' 0 a #################### @@ -129,6 +129,6 @@ c Multi-char delimiters with IFS a b -..c +c banana sausage