diff --git a/doc_src/cmds/string.rst b/doc_src/cmds/string.rst index 34d1998e5..854ff6191 100644 --- a/doc_src/cmds/string.rst +++ b/doc_src/cmds/string.rst @@ -34,7 +34,7 @@ STRING arguments are taken from the command line unless standard input is connec Arguments beginning with ``-`` are normally interpreted as switches; ``--`` causes the following arguments not to be treated as switches even if they begin with ``-``. Switches and required arguments are recognized only on the command line. -Most subcommands accept a ``-q`` or ``--quiet`` switch, which suppresses the usual output but exits with the documented status. +Most subcommands accept a ``-q`` or ``--quiet`` switch, which suppresses the usual output but exits with the documented status. In this case these commands will quit early, without reading all of the available input. The following subcommands are available. diff --git a/src/builtin_string.cpp b/src/builtin_string.cpp index 02c89f25e..203784c95 100644 --- a/src/builtin_string.cpp +++ b/src/builtin_string.cpp @@ -675,6 +675,8 @@ static int string_join_maybe0(parser_t &parser, io_streams_t &streams, int argc, streams.out.append(sep); } streams.out.append(*arg); + } else if (nargs > 1) { + return STATUS_CMD_OK; } nargs++; } @@ -710,6 +712,8 @@ static int string_length(parser_t &parser, io_streams_t &streams, int argc, wcha if (!opts.quiet) { streams.out.append(to_string(n)); streams.out.append(L'\n'); + } else if (nnonempty > 0) { + return STATUS_CMD_OK; } } @@ -1134,6 +1138,7 @@ static int string_match(parser_t &parser, io_streams_t &streams, int argc, wchar if (!matcher->report_matches(*arg)) { return STATUS_INVALID_ARGS; } + if (opts.quiet && matcher->match_count() > 0) return STATUS_CMD_OK; } return matcher->match_count() > 0 ? STATUS_CMD_OK : STATUS_CMD_ERROR; @@ -1387,6 +1392,7 @@ static int string_replace(parser_t &parser, io_streams_t &streams, int argc, wch arg_iterator_t aiter(argv, optind, streams); while (const wcstring *arg = aiter.nextstr()) { if (!replacer->replace_matches(*arg)) return STATUS_INVALID_ARGS; + if (opts.quiet && replacer->replace_count() > 0) return STATUS_CMD_OK; } return replacer->replace_count() > 0 ? STATUS_CMD_OK : STATUS_CMD_ERROR; @@ -1429,6 +1435,8 @@ static int string_split_maybe0(parser_t &parser, io_streams_t &streams, int argc opts.no_empty); } all_splits.push_back(splits); + // If we're quiet, we return early if we've found something to split. + if (opts.quiet && splits.size() > 1) return STATUS_CMD_OK; split_count += splits.size(); arg_count++; } @@ -1557,6 +1565,8 @@ static int string_repeat(parser_t &parser, io_streams_t &streams, int argc, wcha if (!opts.quiet && !is_empty) { streams.out.append(repeated); if (!opts.no_newline) streams.out.append(L"\n"); + } else if (opts.quiet && !is_empty) { + return STATUS_CMD_OK; } } @@ -1621,6 +1631,7 @@ static int string_sub(parser_t &parser, io_streams_t &streams, int argc, wchar_t streams.out.append(L'\n'); } nsub++; + if (opts.quiet) return STATUS_CMD_OK; } return nsub > 0 ? STATUS_CMD_OK : STATUS_CMD_ERROR; @@ -1661,6 +1672,8 @@ static int string_trim(parser_t &parser, io_streams_t &streams, int argc, wchar_ if (!opts.quiet) { streams.out.append(wcstring(*arg, begin, end - begin)); streams.out.append(L'\n'); + } else if (ntrim > 0) { + return STATUS_CMD_OK; } } @@ -1685,6 +1698,8 @@ static int string_transform(parser_t &parser, io_streams_t &streams, int argc, w if (!opts.quiet) { streams.out.append(transformed); streams.out.append(L'\n'); + } else if (n_transformed > 0) { + return STATUS_CMD_OK; } } diff --git a/tests/checks/string.fish b/tests/checks/string.fish index 54c22ee5c..44e6d613f 100644 --- a/tests/checks/string.fish +++ b/tests/checks/string.fish @@ -668,3 +668,16 @@ echo $status # Unmatched capturing groups are treated as empty echo az | string replace -r -- 'a(b.+)?z' 'a:$1z' # CHECK: a:z + +# --quiet should quit early +echo "Checking that --quiet quits early - if this is broken it hangs" +# CHECK: Checking that --quiet quits early - if this is broken it hangs +yes | string match -q y +echo $status +# CHECK: 0 +yes | string length -q +echo $status +# CHECK: 0 +yes | string replace -q y n +echo $status +# CHECK: 0