All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] tee: Add -q, --quiet option to not write to stdout
       [not found]               ` <f78ec1a9-f07f-de20-26cc-4be254e3e921@gmail.com>
@ 2021-01-21 22:49                 ` Alejandro Colomar (man-pages)
  2021-01-21 23:12                   ` [PATCH v2] tee: Add -q, --quiet, --silent " Alejandro Colomar
                                     ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-01-21 22:49 UTC (permalink / raw)
  To: Bernhard Voelker, Alex Henrie, Christian Groessler,
	Pádraig Brady, Michael Kerrisk (man-pages)
  Cc: noloader, Fabrice BAUZAC, Coreutils, freebsd-hackers, tech, linux-api

[CC += mtk, linux-api, freebsd, openbsd]

On 1/21/21 10:26 PM, Alejandro Colomar (man-pages) wrote:
> Hi Berny,
> 
> On 1/21/21 10:01 PM, Bernhard Voelker wrote:
>> On 1/21/21 7:39 PM, Alex Henrie wrote:
>>> That said, I would love to see `tee -q` added to a future revision of
>>> POSIX and adopted everywhere.
>>
>> I like the idea.
>> We have been living for decades without a terminating "pipe end piece",
>> so why hurrying a new option into an implementation of 'tee'?
>> Instead, this could be discussed thoroughly and specified by the OpenGroup
>> and nailed down in a new POSIX issue, and then all implementations
>> could adopt it consistently.
>> Are you willing to start the discussion there?

Hi Berny,

Please don't feel like I'm hurrying with this.
I'm strongly defending my patch to try to
convince you that it's a Good Thing :-)
But if it has to undergo a long discussion
with POSIX, BSD, and whoever, that's fine by me.

I'll send a v2 with --silent in a moment.


Hi Michael,

Talking about designing new APIs,
you might have something to say here,
even if it's not for the kernel.


I also CCd a few lists that might be interested.
Please comment.


Cheers,

Alex

> 
> I am.  However, the Austing Group is a nightmare in terms of login,
> and doing things requiring an account; at least for me.
> 
> I'd prefer that someone else opens a bug there and links to the
> discussion on an open mailing list like this one.
> 
> Do they have an open mailing list?
> 
> Is anyone hepling me report the bug to them?  I should learn at this
> point...
> 
>>
>> BTW: --quiet is usually used to avoid outputting of informational
>> messages (e.g. wget, head, tail, md5sum), while 'tee' would change
>> its functional behavior.
>> Maybe --drain, --drain-stdout, --discard-stdout (-d), --no-stdout (-n),
>> --elide-stdout (-e) or something similar would be more appropriate?
> 
> I stand by -q, --quiet.  Conforming to: grep. Maybe there's some other.
> 
> $ man grep 2>/dev/null | sed -n '/-q, --quiet, --silent/,/^$/p'
>        -q, --quiet, --silent
>               Quiet;  do  not  write  anything to standard output.
>               Exit immediately with zero status if  any  match  is
>               found,  even if an error was detected.  Also see the
>               -s or --no-messages option.
> 
> 
> 
>>
>> Have a nice day,
>> Berny
>>
> 
> Kind regards,
> 
> Alex
> 


-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-21 22:49                 ` [PATCH] tee: Add -q, --quiet option to not write to stdout Alejandro Colomar (man-pages)
@ 2021-01-21 23:12                   ` Alejandro Colomar
  2021-01-22 18:25                     ` Alejandro Colomar (man-pages)
  2021-01-23 14:53                   ` [PATCH] " Alejandro Colomar
  2021-01-24 12:18                   ` [PATCH v3 (resend)] " Alejandro Colomar
  2 siblings, 1 reply; 19+ messages in thread
From: Alejandro Colomar @ 2021-01-21 23:12 UTC (permalink / raw)
  To: Bernhard Voelker, Alex Henrie, Christian Groessler,
	Pádraig Brady, Coreutils
  Cc: Alejandro Colomar, Michael Kerrisk, noloader, Fabrice BAUZAC,
	tech, freebsd-hackers, linux-api

This is useful for using tee to just write to a file,
at the end of a pipeline,
without having to redirect to /dev/null.

Example:
	echo 'foo' | sudo tee -q /etc/foo;
is equivalent to the old (and ugly)
	echo 'foo' | sudo tee /etc/foo >/dev/null;

Tools with a similar interface: grep

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
---

v2: Add --silent synonym to --quiet, per GNU guidelines.
    I tested tee --silent with success.

 src/tee.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/tee.c b/src/tee.c
index c81faea91..68ace983a 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -45,6 +45,9 @@ static bool append;
 /* If true, ignore interrupts. */
 static bool ignore_interrupts;
 
+/* Don't write to stdout */
+static bool quiet;
+
 enum output_error
   {
     output_error_sigpipe,      /* traditional behavior, sigpipe enabled.  */
@@ -61,6 +64,8 @@ static struct option const long_options[] =
   {"append", no_argument, NULL, 'a'},
   {"ignore-interrupts", no_argument, NULL, 'i'},
   {"output-error", optional_argument, NULL, 'p'},
+  {"quiet", no_argument, NULL, 'q'},
+  {"silent", no_argument, NULL, 'q'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -93,6 +98,7 @@ Copy standard input to each FILE, and also to standard output.\n\
 "), stdout);
       fputs (_("\
   -p                        diagnose errors writing to non pipes\n\
+  -q, --quiet, --silent     don't write to standard output\n\
       --output-error[=MODE]   set behavior on write error.  See MODE below\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
@@ -130,6 +136,7 @@ main (int argc, char **argv)
 
   append = false;
   ignore_interrupts = false;
+  quiet = false;
 
   while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
     {
@@ -151,6 +158,10 @@ main (int argc, char **argv)
             output_error = output_error_warn_nopipe;
           break;
 
+        case 'q':
+          quiet = true;
+          break;
+
         case_GETOPT_HELP_CHAR;
 
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -235,8 +246,9 @@ tee_files (int nfiles, char **files)
         break;
 
       /* Write to all NFILES + 1 descriptors.
-         Standard output is the first one.  */
-      for (i = 0; i <= nfiles; i++)
+         Standard output is the first one.
+         If 'quiet' is true, write to descriptors 1 and above (omit stdout)  */
+      for (i = quiet; i <= nfiles; i++)
         if (descriptors[i]
             && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
           {
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-21 23:12                   ` [PATCH v2] tee: Add -q, --quiet, --silent " Alejandro Colomar
@ 2021-01-22 18:25                     ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 19+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-01-22 18:25 UTC (permalink / raw)
  To: Bernhard Voelker, Alex Henrie, Christian Groessler,
	Pádraig Brady, Coreutils
  Cc: Michael Kerrisk, noloader, Fabrice BAUZAC, tech, freebsd-hackers,
	linux-api, juli, ed, oshogbo

I added a few FreeBSD CCs that I found on their tee.c's git blame, 
because the freebsd list rejects external mail.

Please have a look at the proposal below, and the discussion that 
started on gnu coreutil's list.

On 1/22/21 12:12 AM, Alejandro Colomar wrote:
> This is useful for using tee to just write to a file,
> at the end of a pipeline,
> without having to redirect to /dev/null.
> 
> Example:
> 	echo 'foo' | sudo tee -q /etc/foo;
> is equivalent to the old (and ugly)
> 	echo 'foo' | sudo tee /etc/foo >/dev/null;
> 
> Tools with a similar interface: grep
> 
> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
> ---
> 
> v2: Add --silent synonym to --quiet, per GNU guidelines.
>      I tested tee --silent with success.
> 
>   src/tee.c | 16 ++++++++++++++--
>   1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/src/tee.c b/src/tee.c
> index c81faea91..68ace983a 100644
> --- a/src/tee.c
> +++ b/src/tee.c
> @@ -45,6 +45,9 @@ static bool append;
>   /* If true, ignore interrupts. */
>   static bool ignore_interrupts;
>   
> +/* Don't write to stdout */
> +static bool quiet;
> +
>   enum output_error
>     {
>       output_error_sigpipe,      /* traditional behavior, sigpipe enabled.  */
> @@ -61,6 +64,8 @@ static struct option const long_options[] =
>     {"append", no_argument, NULL, 'a'},
>     {"ignore-interrupts", no_argument, NULL, 'i'},
>     {"output-error", optional_argument, NULL, 'p'},
> +  {"quiet", no_argument, NULL, 'q'},
> +  {"silent", no_argument, NULL, 'q'},
>     {GETOPT_HELP_OPTION_DECL},
>     {GETOPT_VERSION_OPTION_DECL},
>     {NULL, 0, NULL, 0}
> @@ -93,6 +98,7 @@ Copy standard input to each FILE, and also to standard output.\n\
>   "), stdout);
>         fputs (_("\
>     -p                        diagnose errors writing to non pipes\n\
> +  -q, --quiet, --silent     don't write to standard output\n\
>         --output-error[=MODE]   set behavior on write error.  See MODE below\n\
>   "), stdout);
>         fputs (HELP_OPTION_DESCRIPTION, stdout);
> @@ -130,6 +136,7 @@ main (int argc, char **argv)
>   
>     append = false;
>     ignore_interrupts = false;
> +  quiet = false;
>   
>     while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
>       {
> @@ -151,6 +158,10 @@ main (int argc, char **argv)
>               output_error = output_error_warn_nopipe;
>             break;
>   
> +        case 'q':
> +          quiet = true;
> +          break;
> +
>           case_GETOPT_HELP_CHAR;
>   
>           case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
> @@ -235,8 +246,9 @@ tee_files (int nfiles, char **files)
>           break;
>   
>         /* Write to all NFILES + 1 descriptors.
> -         Standard output is the first one.  */
> -      for (i = 0; i <= nfiles; i++)
> +         Standard output is the first one.
> +         If 'quiet' is true, write to descriptors 1 and above (omit stdout)  */
> +      for (i = quiet; i <= nfiles; i++)
>           if (descriptors[i]
>               && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
>             {
> 


-- 
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-21 22:49                 ` [PATCH] tee: Add -q, --quiet option to not write to stdout Alejandro Colomar (man-pages)
  2021-01-21 23:12                   ` [PATCH v2] tee: Add -q, --quiet, --silent " Alejandro Colomar
@ 2021-01-23 14:53                   ` Alejandro Colomar
  2021-01-24 12:18                   ` [PATCH v3 (resend)] " Alejandro Colomar
  2 siblings, 0 replies; 19+ messages in thread
From: Alejandro Colomar @ 2021-01-23 14:53 UTC (permalink / raw)
  To: Bernhard Voelker, Alex Henrie, Christian Groessler,
	Pádraig Brady, Coreutils, William Ahern, Erik Auerswald,
	Eric Pruitt, Jeffrey Walton
  Cc: Alejandro Colomar, Michael Kerrisk, Fabrice BAUZAC, tech,
	freebsd-hackers, linux-api, juli, ed, oshogbo

This is useful for using tee to just write to a file,
at the end of a pipeline,
without having to redirect to /dev/null

Example:

echo 'foo' | sudo tee -q /etc/foo;

is equivalent to the old (and ugly)

echo 'foo' | sudo tee /etc/foo >/dev/null;
---

v2: Add --silent synonym to --quiet, per GNU guidelines.
    I tested --silent with success.

v3: Added -q to opstring, which I removed by accident in v2.
    I tested all -q, --quiet and --silent this time.


 src/tee.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/tee.c b/src/tee.c
index c81faea91..1dfa92cf2 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -45,6 +45,9 @@ static bool append;
 /* If true, ignore interrupts. */
 static bool ignore_interrupts;
 
+/* Don't write to stdout */
+static bool quiet;
+
 enum output_error
   {
     output_error_sigpipe,      /* traditional behavior, sigpipe enabled.  */
@@ -61,6 +64,8 @@ static struct option const long_options[] =
   {"append", no_argument, NULL, 'a'},
   {"ignore-interrupts", no_argument, NULL, 'i'},
   {"output-error", optional_argument, NULL, 'p'},
+  {"quiet", no_argument, NULL, 'q'},
+  {"silent", no_argument, NULL, 'q'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -93,6 +98,7 @@ Copy standard input to each FILE, and also to standard output.\n\
 "), stdout);
       fputs (_("\
   -p                        diagnose errors writing to non pipes\n\
+  -q, --quiet, --silent     don't write to standard output\n\
       --output-error[=MODE]   set behavior on write error.  See MODE below\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
@@ -130,8 +136,9 @@ main (int argc, char **argv)
 
   append = false;
   ignore_interrupts = false;
+  quiet = false;
 
-  while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
+  while ((optc = getopt_long (argc, argv, "aipq", long_options, NULL)) != -1)
     {
       switch (optc)
         {
@@ -151,6 +158,10 @@ main (int argc, char **argv)
             output_error = output_error_warn_nopipe;
           break;
 
+        case 'q':
+          quiet = true;
+          break;
+
         case_GETOPT_HELP_CHAR;
 
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -235,8 +246,9 @@ tee_files (int nfiles, char **files)
         break;
 
       /* Write to all NFILES + 1 descriptors.
-         Standard output is the first one.  */
-      for (i = 0; i <= nfiles; i++)
+         Standard output is the first one.
+         If 'quiet' is true, write to descriptors 1 and above (omit stdout)  */
+      for (i = quiet; i <= nfiles; i++)
         if (descriptors[i]
             && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
           {
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-21 22:49                 ` [PATCH] tee: Add -q, --quiet option to not write to stdout Alejandro Colomar (man-pages)
  2021-01-21 23:12                   ` [PATCH v2] tee: Add -q, --quiet, --silent " Alejandro Colomar
  2021-01-23 14:53                   ` [PATCH] " Alejandro Colomar
@ 2021-01-24 12:18                   ` Alejandro Colomar
  2021-01-24 16:11                     ` Teran McKinney
                                       ` (2 more replies)
  2 siblings, 3 replies; 19+ messages in thread
From: Alejandro Colomar @ 2021-01-24 12:18 UTC (permalink / raw)
  To: Bernhard Voelker, Alex Henrie, Christian Groessler,
	Pádraig Brady, Coreutils, William Ahern, Erik Auerswald,
	Eric Pruitt, Jeffrey Walton
  Cc: Alejandro Colomar, Michael Kerrisk, Fabrice BAUZAC, tech,
	freebsd-hackers, linux-api, juli, ed, oshogbo

This is useful for using tee to just write to a file,
at the end of a pipeline,
without having to redirect to /dev/null

Example:

echo 'foo' | sudo tee -q /etc/foo;

is equivalent to the old (and ugly)

echo 'foo' | sudo tee /etc/foo >/dev/null;

Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
---

Resend as v3. I forgot to change the subject line.
Everything else is the same as in
<20210123145356.53962-1-alx.manpages@gmail.com>.

 src/tee.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/tee.c b/src/tee.c
index c81faea91..1dfa92cf2 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -45,6 +45,9 @@ static bool append;
 /* If true, ignore interrupts. */
 static bool ignore_interrupts;
 
+/* Don't write to stdout */
+static bool quiet;
+
 enum output_error
   {
     output_error_sigpipe,      /* traditional behavior, sigpipe enabled.  */
@@ -61,6 +64,8 @@ static struct option const long_options[] =
   {"append", no_argument, NULL, 'a'},
   {"ignore-interrupts", no_argument, NULL, 'i'},
   {"output-error", optional_argument, NULL, 'p'},
+  {"quiet", no_argument, NULL, 'q'},
+  {"silent", no_argument, NULL, 'q'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
   {NULL, 0, NULL, 0}
@@ -93,6 +98,7 @@ Copy standard input to each FILE, and also to standard output.\n\
 "), stdout);
       fputs (_("\
   -p                        diagnose errors writing to non pipes\n\
+  -q, --quiet, --silent     don't write to standard output\n\
       --output-error[=MODE]   set behavior on write error.  See MODE below\n\
 "), stdout);
       fputs (HELP_OPTION_DESCRIPTION, stdout);
@@ -130,8 +136,9 @@ main (int argc, char **argv)
 
   append = false;
   ignore_interrupts = false;
+  quiet = false;
 
-  while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
+  while ((optc = getopt_long (argc, argv, "aipq", long_options, NULL)) != -1)
     {
       switch (optc)
         {
@@ -151,6 +158,10 @@ main (int argc, char **argv)
             output_error = output_error_warn_nopipe;
           break;
 
+        case 'q':
+          quiet = true;
+          break;
+
         case_GETOPT_HELP_CHAR;
 
         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -235,8 +246,9 @@ tee_files (int nfiles, char **files)
         break;
 
       /* Write to all NFILES + 1 descriptors.
-         Standard output is the first one.  */
-      for (i = 0; i <= nfiles; i++)
+         Standard output is the first one.
+         If 'quiet' is true, write to descriptors 1 and above (omit stdout)  */
+      for (i = quiet; i <= nfiles; i++)
         if (descriptors[i]
             && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
           {
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 12:18                   ` [PATCH v3 (resend)] " Alejandro Colomar
@ 2021-01-24 16:11                     ` Teran McKinney
  2021-01-24 16:22                       ` Alejandro Colomar (man-pages)
  2021-01-24 17:51                     ` Otto Moerbeek
  2021-01-25 16:06                     ` Philipp-Joachim Ost
  2 siblings, 1 reply; 19+ messages in thread
From: Teran McKinney @ 2021-01-24 16:11 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Bernhard Voelker, Alex Henrie, Christian Groessler,
	P??draig Brady, Coreutils, William Ahern, Erik Auerswald,
	Eric Pruitt, Jeffrey Walton, Michael Kerrisk, Fabrice BAUZAC,
	tech, freebsd-hackers, linux-api, juli, ed, oshogbo

On 2021-01-24 13-18-46    , Alejandro Colomar wrote:
> This is useful for using tee to just write to a file,
> at the end of a pipeline,
> without having to redirect to /dev/null
> 
> Example:
> 
> echo 'foo' | sudo tee -q /etc/foo;
> 
> is equivalent to the old (and ugly)
> 
> echo 'foo' | sudo tee /etc/foo >/dev/null;
> 
> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
> ---
> 
> Resend as v3. I forgot to change the subject line.
> Everything else is the same as in
> <20210123145356.53962-1-alx.manpages@gmail.com>.
> 
>  src/tee.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/src/tee.c b/src/tee.c
> index c81faea91..1dfa92cf2 100644
> --- a/src/tee.c
> +++ b/src/tee.c
> @@ -45,6 +45,9 @@ static bool append;
>  /* If true, ignore interrupts. */
>  static bool ignore_interrupts;
>  
> +/* Don't write to stdout */
> +static bool quiet;
> +
>  enum output_error
>    {
>      output_error_sigpipe,      /* traditional behavior, sigpipe enabled.  */
> @@ -61,6 +64,8 @@ static struct option const long_options[] =
>    {"append", no_argument, NULL, 'a'},
>    {"ignore-interrupts", no_argument, NULL, 'i'},
>    {"output-error", optional_argument, NULL, 'p'},
> +  {"quiet", no_argument, NULL, 'q'},
> +  {"silent", no_argument, NULL, 'q'},
>    {GETOPT_HELP_OPTION_DECL},
>    {GETOPT_VERSION_OPTION_DECL},
>    {NULL, 0, NULL, 0}
> @@ -93,6 +98,7 @@ Copy standard input to each FILE, and also to standard output.\n\
>  "), stdout);
>        fputs (_("\
>    -p                        diagnose errors writing to non pipes\n\
> +  -q, --quiet, --silent     don't write to standard output\n\
>        --output-error[=MODE]   set behavior on write error.  See MODE below\n\
>  "), stdout);
>        fputs (HELP_OPTION_DESCRIPTION, stdout);
> @@ -130,8 +136,9 @@ main (int argc, char **argv)
>  
>    append = false;
>    ignore_interrupts = false;
> +  quiet = false;
>  
> -  while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
> +  while ((optc = getopt_long (argc, argv, "aipq", long_options, NULL)) != -1)
>      {
>        switch (optc)
>          {
> @@ -151,6 +158,10 @@ main (int argc, char **argv)
>              output_error = output_error_warn_nopipe;
>            break;
>  
> +        case 'q':
> +          quiet = true;
> +          break;
> +
>          case_GETOPT_HELP_CHAR;
>  
>          case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
> @@ -235,8 +246,9 @@ tee_files (int nfiles, char **files)
>          break;
>  
>        /* Write to all NFILES + 1 descriptors.
> -         Standard output is the first one.  */
> -      for (i = 0; i <= nfiles; i++)
> +         Standard output is the first one.
> +         If 'quiet' is true, write to descriptors 1 and above (omit stdout)  */
> +      for (i = quiet; i <= nfiles; i++)
>          if (descriptors[i]
>              && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
>            {
> -- 
> 2.30.0
> 
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"

Hi,

Why is this a thing?

The point of tee is to write a file *and* to stdout. If you don't want use that, use:

`> file`

To overwrite.

Or

`>> file`

To append.

I guess the only reason this would be used is if you wanted to write
multiple files at the same time, which tee supports.

-Teran

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 16:11                     ` Teran McKinney
@ 2021-01-24 16:22                       ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 19+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-01-24 16:22 UTC (permalink / raw)
  To: Teran McKinney
  Cc: Bernhard Voelker, Alex Henrie, Christian Groessler,
	P??draig Brady, Coreutils, William Ahern, Erik Auerswald,
	Eric Pruitt, Jeffrey Walton, Michael Kerrisk, Fabrice BAUZAC,
	tech, freebsd-hackers, linux-api, juli, ed, oshogbo

On 1/24/21 5:11 PM, Teran McKinney wrote:
> On 2021-01-24 13-18-46    , Alejandro Colomar wrote:
>> This is useful for using tee to just write to a file,
>> at the end of a pipeline,
>> without having to redirect to /dev/null
>>
>> Example:
>>
>> echo 'foo' | sudo tee -q /etc/foo;
>>
>> is equivalent to the old (and ugly)
>>
>> echo 'foo' | sudo tee /etc/foo >/dev/null;
>>
>> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
>> ---
[...]
> 
> Hi,
> 
> Why is this a thing?
> 
> The point of tee is to write a file *and* to stdout. If you don't want use that, use:
> 
> `> file`
> 
> To overwrite.
> 
> Or
> 
> `>> file`
> 
> To append.
> 
> I guess the only reason this would be used is if you wanted to write
> multiple files at the same time, which tee supports.
> 
> -Teran
> 


Hi Teran,

The rationale is that protected files can't be modified with '>', unless
you give superuser rights to the whole shell.  If you want fine-grained
control over the rights of the tools in the pipeline, you'll come to
times where you want the write step to be the only one to have those,
and you can't [sudo >] nor [sudo >>], which by the way I would consider
an even better solution, but which would require much more work, and
designing a completely new idiom for it, which would face much more
objection too.

Regards,

Alex

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 12:18                   ` [PATCH v3 (resend)] " Alejandro Colomar
  2021-01-24 16:11                     ` Teran McKinney
@ 2021-01-24 17:51                     ` Otto Moerbeek
  2021-01-24 17:58                       ` Theo de Raadt
  2021-01-24 20:01                       ` Alex Henrie
  2021-01-25 16:06                     ` Philipp-Joachim Ost
  2 siblings, 2 replies; 19+ messages in thread
From: Otto Moerbeek @ 2021-01-24 17:51 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Bernhard Voelker, Alex Henrie, Christian Groessler,
	Pádraig Brady, Coreutils, William Ahern, Erik Auerswald,
	Eric Pruitt, Jeffrey Walton, Michael Kerrisk, Fabrice BAUZAC,
	tech, freebsd-hackers, linux-api, juli, ed, oshogbo

On Sun, Jan 24, 2021 at 01:18:46PM +0100, Alejandro Colomar wrote:

> This is useful for using tee to just write to a file,
> at the end of a pipeline,
> without having to redirect to /dev/null
> 
> Example:
> 
> echo 'foo' | sudo tee -q /etc/foo;
> 
> is equivalent to the old (and ugly)

You keep repeating "ugly" as the reason you are wanting this.

I consider adding special options to command to solve an imagined
issue that can be solved with a general concept like redirection ugly.
Please stop pushing your diff to this list. So far nobody showed any
interest.

	-Otto

> 
> echo 'foo' | sudo tee /etc/foo >/dev/null;
> 
> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
> ---
> 
> Resend as v3. I forgot to change the subject line.
> Everything else is the same as in
> <20210123145356.53962-1-alx.manpages@gmail.com>.
> 
>  src/tee.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/src/tee.c b/src/tee.c
> index c81faea91..1dfa92cf2 100644
> --- a/src/tee.c
> +++ b/src/tee.c
> @@ -45,6 +45,9 @@ static bool append;
>  /* If true, ignore interrupts. */
>  static bool ignore_interrupts;
>  
> +/* Don't write to stdout */
> +static bool quiet;
> +
>  enum output_error
>    {
>      output_error_sigpipe,      /* traditional behavior, sigpipe enabled.  */
> @@ -61,6 +64,8 @@ static struct option const long_options[] =
>    {"append", no_argument, NULL, 'a'},
>    {"ignore-interrupts", no_argument, NULL, 'i'},
>    {"output-error", optional_argument, NULL, 'p'},
> +  {"quiet", no_argument, NULL, 'q'},
> +  {"silent", no_argument, NULL, 'q'},
>    {GETOPT_HELP_OPTION_DECL},
>    {GETOPT_VERSION_OPTION_DECL},
>    {NULL, 0, NULL, 0}
> @@ -93,6 +98,7 @@ Copy standard input to each FILE, and also to standard output.\n\
>  "), stdout);
>        fputs (_("\
>    -p                        diagnose errors writing to non pipes\n\
> +  -q, --quiet, --silent     don't write to standard output\n\
>        --output-error[=MODE]   set behavior on write error.  See MODE below\n\
>  "), stdout);
>        fputs (HELP_OPTION_DESCRIPTION, stdout);
> @@ -130,8 +136,9 @@ main (int argc, char **argv)
>  
>    append = false;
>    ignore_interrupts = false;
> +  quiet = false;
>  
> -  while ((optc = getopt_long (argc, argv, "aip", long_options, NULL)) != -1)
> +  while ((optc = getopt_long (argc, argv, "aipq", long_options, NULL)) != -1)
>      {
>        switch (optc)
>          {
> @@ -151,6 +158,10 @@ main (int argc, char **argv)
>              output_error = output_error_warn_nopipe;
>            break;
>  
> +        case 'q':
> +          quiet = true;
> +          break;
> +
>          case_GETOPT_HELP_CHAR;
>  
>          case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
> @@ -235,8 +246,9 @@ tee_files (int nfiles, char **files)
>          break;
>  
>        /* Write to all NFILES + 1 descriptors.
> -         Standard output is the first one.  */
> -      for (i = 0; i <= nfiles; i++)
> +         Standard output is the first one.
> +         If 'quiet' is true, write to descriptors 1 and above (omit stdout)  */
> +      for (i = quiet; i <= nfiles; i++)
>          if (descriptors[i]
>              && fwrite (buffer, bytes_read, 1, descriptors[i]) != 1)
>            {
> -- 
> 2.30.0
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 17:51                     ` Otto Moerbeek
@ 2021-01-24 17:58                       ` Theo de Raadt
  2021-01-24 20:01                       ` Alex Henrie
  1 sibling, 0 replies; 19+ messages in thread
From: Theo de Raadt @ 2021-01-24 17:58 UTC (permalink / raw)
  To: Otto Moerbeek
  Cc: Alejandro Colomar, Bernhard Voelker, Alex Henrie,
	Christian Groessler, Pádraig Brady, Coreutils,
	William Ahern, Erik Auerswald, Eric Pruitt, Jeffrey Walton,
	Michael Kerrisk, Fabrice BAUZAC, tech, freebsd-hackers,
	linux-api, juli, ed, oshogbo

Otto Moerbeek <otto@drijf.net> wrote:

> On Sun, Jan 24, 2021 at 01:18:46PM +0100, Alejandro Colomar wrote:
> 
> > This is useful for using tee to just write to a file,
> > at the end of a pipeline,
> > without having to redirect to /dev/null
> > 
> > Example:
> > 
> > echo 'foo' | sudo tee -q /etc/foo;
> > 
> > is equivalent to the old (and ugly)
> 
> You keep repeating "ugly" as the reason you are wanting this.
> 
> I consider adding special options to command to solve an imagined
> issue that can be solved with a general concept like redirection ugly.
> Please stop pushing your diff to this list. So far nobody showed any
> interest.

I also see ZERO reason for this change.

This change will encourage the creation of non-portable scripts, which
harms backwards compatibility and portability, while increasing the
cognitive cost of building software in a simple and useable command
ecosystem.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 17:51                     ` Otto Moerbeek
  2021-01-24 17:58                       ` Theo de Raadt
@ 2021-01-24 20:01                       ` Alex Henrie
  2021-01-24 20:22                         ` Otto Moerbeek
  2021-01-25  4:03                         ` Bernhard Voelker
  1 sibling, 2 replies; 19+ messages in thread
From: Alex Henrie @ 2021-01-24 20:01 UTC (permalink / raw)
  To: Otto Moerbeek
  Cc: Alejandro Colomar, Bernhard Voelker, Christian Groessler,
	Pádraig Brady, Coreutils, William Ahern, Erik Auerswald,
	Eric Pruitt, Jeffrey Walton, Michael Kerrisk, Fabrice BAUZAC,
	tech, freebsd-hackers, linux-api, juli, ed, oshogbo,
	Roman Czyborra, Jim Meyering

On Sun, Jan 24, 2021 at 10:51 AM Otto Moerbeek <otto@drijf.net> wrote:
>
> Please stop pushing your diff to this list. So far nobody showed any
> interest.

I am definitely interested. Bernhard Voelker seemed to express
interest as well, conditional on -q being added to POSIX first.[1]
Also, a --quiet flag was proposed back in 2001 by Roman Czyborra [2]
and Jim Meyering expressed support for the idea.[3]

-Alex

[1] https://lists.gnu.org/archive/html/coreutils/2021-01/msg00043.html
[2] https://lists.gnu.org/archive/html/bug-sh-utils/2001-05/msg00024.html
[3] https://lists.gnu.org/archive/html/bug-sh-utils/2001-05/msg00039.html

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 20:01                       ` Alex Henrie
@ 2021-01-24 20:22                         ` Otto Moerbeek
  2021-01-25  4:03                         ` Bernhard Voelker
  1 sibling, 0 replies; 19+ messages in thread
From: Otto Moerbeek @ 2021-01-24 20:22 UTC (permalink / raw)
  To: Alex Henrie
  Cc: Alejandro Colomar, Bernhard Voelker, Christian Groessler,
	Pádraig Brady, Coreutils, William Ahern, Erik Auerswald,
	Eric Pruitt, Jeffrey Walton, Michael Kerrisk, Fabrice BAUZAC,
	tech, freebsd-hackers, linux-api, juli, ed, oshogbo,
	Roman Czyborra, Jim Meyering

On Sun, Jan 24, 2021 at 01:01:45PM -0700, Alex Henrie wrote:

> On Sun, Jan 24, 2021 at 10:51 AM Otto Moerbeek <otto@drijf.net> wrote:
> >
> > Please stop pushing your diff to this list. So far nobody showed any
> > interest.
> 
> I am definitely interested. Bernhard Voelker seemed to express
> interest as well, conditional on -q being added to POSIX first.[1]
> Also, a --quiet flag was proposed back in 2001 by Roman Czyborra [2]
> and Jim Meyering expressed support for the idea.[3]
> 
> -Alex
> 
> [1] https://lists.gnu.org/archive/html/coreutils/2021-01/msg00043.html
> [2] https://lists.gnu.org/archive/html/bug-sh-utils/2001-05/msg00024.html
> [3] https://lists.gnu.org/archive/html/bug-sh-utils/2001-05/msg00039.html

"This list" is the OpenBSD tech list, sorry I did leave out this
context info.

	-Otto

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 20:01                       ` Alex Henrie
  2021-01-24 20:22                         ` Otto Moerbeek
@ 2021-01-25  4:03                         ` Bernhard Voelker
  2021-01-25 11:33                           ` Alejandro Colomar (man-pages)
                                             ` (2 more replies)
  1 sibling, 3 replies; 19+ messages in thread
From: Bernhard Voelker @ 2021-01-25  4:03 UTC (permalink / raw)
  To: Alex Henrie, Otto Moerbeek, Coreutils
  Cc: Alejandro Colomar, Fabrice BAUZAC, juli, Jeffrey Walton,
	freebsd-hackers, William Ahern, Roman Czyborra, oshogbo, tech,
	Christian Groessler, linux-api, Michael Kerrisk, ed, Eric Pruitt

[-- Attachment #1: Type: text/plain, Size: 2664 bytes --]

On 1/24/21 9:01 PM, Alex Henrie wrote:
> I am definitely interested. Bernhard Voelker seemed to express
> interest as well, conditional on -q being added to POSIX first.[1]

Just to clarify: I'm not as enthusiastic to add that option as it
may have sounded.

Let me put it like this: if -q once gets standardized by POSIX,
then we'd take it over in the GNU tee implementation.

Let me summarize so far:
The suggestion is to solve the problem to save some data coming from
a pipe as a different user.
There are at least those known solutions:
  - use > or >> redirection.
  - use dd(1)

I have the impression that a home for this feature was searched
in any tool, and as tee(1) already knew how to write to a file,
had the "append" feature, and is often used in pipes, it was
tempting to add it there.

But looking deeper, --quiet doesn't seem to fit well into 'tee'.
It even contradicts to the title line in the man page:
  "read from standard input and write to standard output and files"

An off-tech argument: ask a local plumber if he'd would ever use
a tee piece instead of a pipe end piece.  I guess he would only
if he wouldn't have anything else at hand.

A word to the proposed patch: what should happen, if the user does
not give a file?
  A | B | tee -q
The patch just silently ignored that situation which feels wrong.

Therefore, adding a feature which does not really fit is wrong, and
contradicts the one-tool-for-one-purpose UNIX philosophy.

OTOH I understand that there's a little gap in the tool landscape.
Astonishingly, there doesn't seem to exist a trivial tool to redirect
from standard input (or any other input file descriptor) to a file.
I wrote such a little tool in the attached:

  $ src/sink --help
  Usage: src/sink [OPTION]... FILE
  Copy input stream to FILE.

  Mandatory arguments to long options are mandatory for short options too.

    -a, --append              append to the given FILE, do not overwrite
    -c, --create              ensure to create FILE, error if exists
    -i, --input-stream=FD     read from stream FD instead of standard input

  The default input stream number FD is 0, representing the standard input.

This allows not only to copy data from standard input, but from any
file descriptor open for reading.  It also allows control over
how the output file will be opened (e.g. with O_CREAT|E_EXCL).

The OPs case would look like:

  echo 'foo' | sudo sink /etc/foo
or
  echo 'foo' | sudo sink -a /etc/foo  # append.
or
  echo 'foo' | sudo sink -c /etc/foo  # ensure creation of the file.

I'm not sure if this will ever be considered for inclusion -
I just did it "for fun". ;-)

Have a nice day,
Berny

[-- Attachment #2: 0001-sink-add-new-program.patch --]
[-- Type: text/x-patch, Size: 21229 bytes --]

From 68473fb37ccfd65473ac186db4bd3bcc29560a40 Mon Sep 17 00:00:00 2001
From: Bernhard Voelker <mail@bernhard-voelker.de>
Date: Mon, 25 Jan 2021 04:05:44 +0100
Subject: [PATCH] sink: add new program

* man/sink.x: Add file.
* src/sink.c: Likewise.
* AUTHORS (sink): Add entry.
* NEWS (New programs): Likewise.
* man/.gitignore (sink.1): Likewise.
* man/local.mk (man/sink.1): Likewise.
* po/POTFILES.in (src/sink.c): Likewise.
* src/.gitignore (sink): Likewise.
* README: Add the new tool to the list of programs.
* build-aux/gen-lists-of-programs.sh (normal_progs): Likewise.
* scripts/git-hooks/commit-msg (valid): Likewise.
* doc/coreutils.texi (sink invocation): Document the tool.
* tests/misc/sink.sh: Add a test.
* tests/local.mk (all_tests): Reference it.
* tests/misc/help-version.sh (sink_setup): Add test setup snippet.
---
 AUTHORS                            |   1 +
 NEWS                               |   4 +
 README                             |   6 +-
 build-aux/gen-lists-of-programs.sh |   1 +
 doc/coreutils.texi                 |  87 +++++++++++-
 man/.gitignore                     |   1 +
 man/local.mk                       |   1 +
 man/sink.x                         |   6 +
 po/POTFILES.in                     |   1 +
 scripts/git-hooks/commit-msg       |   2 +-
 src/.gitignore                     |   1 +
 src/sink.c                         | 205 +++++++++++++++++++++++++++++
 tests/local.mk                     |   1 +
 tests/misc/help-version.sh         |   1 +
 tests/misc/sink.sh                 | 146 ++++++++++++++++++++
 15 files changed, 456 insertions(+), 8 deletions(-)
 create mode 100644 man/sink.x
 create mode 100644 src/sink.c
 create mode 100755 tests/misc/sink.sh

diff --git a/AUTHORS b/AUTHORS
index 46948d5fd..5790616b4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -79,6 +79,7 @@ sha384sum: Ulrich Drepper, Scott Miller, David Madore
 sha512sum: Ulrich Drepper, Scott Miller, David Madore
 shred: Colin Plumb
 shuf: Paul Eggert
+sink: Bernhard Voelker
 sleep: Jim Meyering, Paul Eggert
 sort: Mike Haertel, Paul Eggert
 split: Torbjorn Granlund, Richard M. Stallman
diff --git a/NEWS b/NEWS
index a6ba96450..3323b3300 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** New programs
+
+  sink: copy data from an input stream to a file.
+
 ** Bug fixes
 
   cp -a --attributes-only now never removes destination files,
diff --git a/README b/README
index 6cb7c2226..da98eb86f 100644
--- a/README
+++ b/README
@@ -13,9 +13,9 @@ The programs that can be built with this package are:
   id install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp
   mv nice nl nohup nproc numfmt od paste pathchk pinky pr printenv printf ptx
   pwd readlink realpath rm rmdir runcon seq sha1sum sha224sum sha256sum
-  sha384sum sha512sum shred shuf sleep sort split stat stdbuf stty sum sync
-  tac tail tee test timeout touch tr true truncate tsort tty uname unexpand
-  uniq unlink uptime users vdir wc who whoami yes
+  sha384sum sha512sum shred shuf sink sleep sort split stat stdbuf stty sum
+  sync tac tail tee test timeout touch tr true truncate tsort tty uname
+  unexpand uniq unlink uptime users vdir wc who whoami yes
 
 See the file NEWS for a list of major changes in the current release.
 
diff --git a/build-aux/gen-lists-of-programs.sh b/build-aux/gen-lists-of-programs.sh
index 3ec9a6dd1..e9921e912 100755
--- a/build-aux/gen-lists-of-programs.sh
+++ b/build-aux/gen-lists-of-programs.sh
@@ -112,6 +112,7 @@ normal_progs='
     sha512sum
     shred
     shuf
+    sink
     sleep
     sort
     split
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 94c9fbfa5..743276bac 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -109,6 +109,7 @@
 * sha2: (coreutils)sha2 utilities.              Print or check SHA-2 digests.
 * shred: (coreutils)shred invocation.           Remove files more securely.
 * shuf: (coreutils)shuf invocation.             Shuffling text files.
+* sink: (coreutils)sink invocation.             Redirect a stream to a file.
 * sleep: (coreutils)sleep invocation.           Delay for a specified time.
 * sort: (coreutils)sort invocation.             Sort text files.
 * split: (coreutils)split invocation.           Split into pieces.
@@ -199,7 +200,7 @@ Free Documentation License''.
 * Disk usage::                   df du stat sync truncate
 * Printing text::                echo printf yes
 * Conditions::                   false true test expr
-* Redirection::                  tee
+* Redirection::                  sink tee
 * File name manipulation::       dirname basename pathchk mktemp realpath
 * Working context::              pwd stty printenv tty
 * User information::             id logname whoami groups users who
@@ -384,6 +385,7 @@ Conditions
 
 Redirection
 
+* sink invocation::              Redirect a stream to a file
 * tee invocation::               Redirect output to multiple files or processes
 
 File name manipulation
@@ -13744,14 +13746,91 @@ expr index + index a
 @cindex commands for redirection
 
 Unix shells commonly provide several forms of @dfn{redirection}---ways
-to change the input source or output destination of a command.  But one
-useful redirection is performed by a separate command, not by the shell;
-it's described here.
+to change the input source or output destination of a command.  But two
+useful redirections are performed by the separate commands, not by the shell;
+they're described here.
 
 @menu
+* sink invocation::             Redirect a stream to a file.
 * tee invocation::              Redirect output to multiple files or processes.
 @end menu
 
+@node sink invocation
+@section @command{sink}: Redirect a stream to a file
+
+@pindex sink
+@cindex pipe fitting
+@cindex source, file descriptor input
+@cindex read from a stream and write to a file
+
+The @command{sink} command copies the data of an input stream to a file given
+as argument.  The input stream defaults to the standard input, and can be
+changed to any other file descriptor open for reading.
+Synopsis:
+
+@example
+sink [@var{option}]@dots{} @var{file}
+@end example
+
+The program accepts the following options.  Also see @ref{Common options}.
+
+@table @samp
+@item -a
+@itemx --append
+@opindex -a
+@opindex --append
+Append the input data to the given file rather than overwriting it.
+
+@item -c
+@itemx --create
+@opindex -c
+@opindex --create
+Ensure that the program creates the given output file;
+fail if it already exists.
+
+@item -i @var{fd}
+@itemx --input-stream=@var{fd}
+@opindex -i
+@opindex --input-stream
+Read the input data from the stream associated to the numeric
+file descriptor @var{fd}.
+Without this option, the input file descriptor defaults to standard input.
+@end table
+
+The @command{sink} command may be useful to write the data at the end of a pipe
+to a file without using a shell redirection operator.
+@example
+cat file1 \
+  | grep pattern \
+  | tee file2 file3 \
+  | tr '[a-z]' '[A-Z]' \
+  | sink file4
+@end example
+
+Another example is to use it at the end of a pipe to write something via
+@command{sudo} into a file owned by the superuser.
+
+@example
+echo '127.0.0.2 localalias' | sudo sink -a /etc/hosts
+@end example
+
+Here is a more complex example to redirect the input from file descriptor
+@samp{6} which is associated to a pipe (instead of the default, standard input).
+
+@example
+$ mkfifo pipe \
+    && src/sink -i6 -c file 6<pipe &
+$ ( exec 1>pipe; \
+    for n in 1 2 3; do \
+      echo step$n; \
+      sleep 1; \
+    done >pipe; \
+    rm -f pipe )
+$ cat file
+step1
+step2
+step3
+@end example
 
 @node tee invocation
 @section @command{tee}: Redirect output to multiple files or processes
diff --git a/man/.gitignore b/man/.gitignore
index 4eecb7833..d4551d74f 100644
--- a/man/.gitignore
+++ b/man/.gitignore
@@ -74,6 +74,7 @@ sha384sum.1
 sha512sum.1
 shred.1
 shuf.1
+sink.1
 sleep.1
 sort.1
 split.1
diff --git a/man/local.mk b/man/local.mk
index d23699bae..3f407f4ee 100644
--- a/man/local.mk
+++ b/man/local.mk
@@ -141,6 +141,7 @@ man/sha384sum.1: src/sha384sum$(EXEEXT)
 man/sha512sum.1: src/sha512sum$(EXEEXT)
 man/shred.1:     src/shred$(EXEEXT)
 man/shuf.1:      src/shuf$(EXEEXT)
+man/sink.1:      src/sink$(EXEEXT)
 man/sleep.1:     src/sleep$(EXEEXT)
 man/sort.1:      src/sort$(EXEEXT)
 man/split.1:     src/split$(EXEEXT)
diff --git a/man/sink.x b/man/sink.x
new file mode 100644
index 000000000..a4a0b5725
--- /dev/null
+++ b/man/sink.x
@@ -0,0 +1,6 @@
+[NAME]
+sink \- copy data from an input stream to a file
+[DESCRIPTION]
+.\" Add any additional description here
+[SEE ALSO]
+cat(1), tee(1)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5f9c8fc50..7cf439069 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -113,6 +113,7 @@ src/seq.c
 src/set-fields.c
 src/shred.c
 src/shuf.c
+src/sink.c
 src/sleep.c
 src/sort.c
 src/split.c
diff --git a/scripts/git-hooks/commit-msg b/scripts/git-hooks/commit-msg
index 8a4b894ef..8ade59b8e 100755
--- a/scripts/git-hooks/commit-msg
+++ b/scripts/git-hooks/commit-msg
@@ -20,7 +20,7 @@ my @valid = qw(
     install join kill link ln logname ls md5sum mkdir mkfifo mknod mktemp
     mv nice nl nohup nproc numfmt od paste pathchk pinky pr printenv printf
     ptx pwd readlink realpath rm rmdir runcon seq sha1sum sha224sum sha256sum
-    sha384sum sha512sum shred shuf sleep sort split stat stdbuf stty
+    sha384sum sha512sum shred shuf sink sleep sort split stat stdbuf stty
     sum sync tac tail tee test timeout touch tr true truncate tsort
     tty uname unexpand uniq unlink uptime users vdir wc who whoami yes
 
diff --git a/src/.gitignore b/src/.gitignore
index 86d82ad4b..eedb4d856 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -86,6 +86,7 @@ sha384sum
 sha512sum
 shred
 shuf
+sink
 sleep
 sort
 split
diff --git a/src/sink.c b/src/sink.c
new file mode 100644
index 000000000..c7571fdf4
--- /dev/null
+++ b/src/sink.c
@@ -0,0 +1,205 @@
+/* sink - read from standard input and write a file.
+   Copyright (C) 2021 Free Software Foundation, Inc.
+
+   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 <https://www.gnu.org/licenses/>.  */
+
+/* Bernhard Voelker */
+
+#include <config.h>
+#include <sys/types.h>
+#include <getopt.h>
+
+#include "system.h"
+#include "die.h"
+#include "error.h"
+#include "fadvise.h"
+#include "xbinary-io.h"
+#include "xdectoint.h"
+
+/* The official name of this program (e.g., no 'g' prefix).  */
+#define PROGRAM_NAME "sink"
+
+#define AUTHORS \
+  proper_name ("Bernhard Voelker")
+
+/* Upper bound on getdtablesize().  See gnulib/lib/fcntl.c.  */
+#define OPEN_MAX_MAX 0x10000
+
+/* If true, append to output file rather than truncating it. */
+static bool flag_append;
+
+/* If true, ensure to create the output FILE: mode O_CREAT | O_EXCL.  */
+static bool flag_creat;
+
+/* Input file descriptor, default to stdin.  */
+static int input_stream = STDIN_FILENO;
+
+static struct option const long_options[] =
+{
+  {"append", no_argument, NULL, 'a'},
+  {"create", no_argument, NULL, 'c'},
+  {"input-stream", required_argument, NULL, 'i'},
+  {GETOPT_HELP_OPTION_DECL},
+  {GETOPT_VERSION_OPTION_DECL},
+  {NULL, 0, NULL, 0}
+};
+
+void
+usage (int status)
+{
+  if (status != EXIT_SUCCESS)
+    emit_try_help ();
+  else
+    {
+      printf (_("Usage: %s [OPTION]... FILE\n"), program_name);
+      fputs (_("\
+Copy input stream to FILE.\n\
+"), stdout);
+
+      emit_mandatory_arg_note ();
+
+      fputs (_("\n\
+  -a, --append              append to the given FILE, do not overwrite\n\
+"), stdout);
+      fputs (_("\
+  -c, --create              ensure to create FILE, error if exists\n\
+"), stdout);
+      fputs (_("\
+  -i, --input-stream=FD     read from stream FD instead of standard input\n\
+"), stdout);
+      fputs (_("\n\
+The default input stream number FD is 0, representing the standard input.\n\
+"), stdout);
+      emit_ancillary_info (PROGRAM_NAME);
+    }
+  exit (status);
+}
+
+/* Copy data from file descriptor INFD to file FILENAME.
+   Return true if successful.  */
+
+static bool
+sink (int src_fd, char *filename)
+{
+  char buffer[BUFSIZ];
+  ssize_t bytes_read = 0;
+  bool ok = true;
+
+  xset_binary_mode (src_fd, O_BINARY);
+  fadvise (fdopen (src_fd, "r"), FADVISE_SEQUENTIAL);
+
+  char const *mode_string =
+    (O_BINARY
+     ? (flag_append ? "ab" : "wb")
+     : (flag_append ? "a" : "w"));
+
+  /* Both --append and --create may create the file.  */
+  int open_flags = O_WRONLY | O_BINARY | O_NOCTTY | O_CREAT;
+  if (flag_creat)
+    open_flags |= O_EXCL;
+
+  open_flags |= flag_append ? O_APPEND : O_TRUNC;
+
+  int dest_fd = open (filename, open_flags, MODE_RW_UGO);
+  if (dest_fd < 0)
+    die (EXIT_FAILURE, errno, "%s: %s", _("open failed"), quoteaf (filename));
+
+  FILE *dest_fp = fdopen (dest_fd, mode_string);
+  if (dest_fp == NULL)
+    die (EXIT_FAILURE, errno, "%s", quoteaf (filename));
+
+  setvbuf (dest_fp, NULL, _IONBF, 0);
+
+  while (true)
+    {
+      bytes_read = read (src_fd, buffer, sizeof buffer);
+      if (bytes_read < 0 && errno == EINTR)
+        continue;
+      if (bytes_read <= 0)
+        break;
+
+      if (fwrite (buffer, bytes_read, 1, dest_fp) != 1)
+        die (EXIT_FAILURE, errno, "%s: %s", _("write failed"),
+             quoteaf (filename));
+    }
+
+  if (bytes_read == -1)
+    die (EXIT_FAILURE, errno, _("file descriptor %d: read failed"), src_fd);
+
+  if (close (src_fd) != 0)
+    die (EXIT_FAILURE, errno, _("file descriptor %d: close failed"), src_fd);
+
+  if (fclose (dest_fp) != 0)
+    die (EXIT_FAILURE, errno, "%s: %s", _("close failed"), quoteaf (filename));
+
+  return ok;
+}
+
+int
+main (int argc, char **argv)
+{
+  int optc;
+
+  initialize_main (&argc, &argv);
+  set_program_name (argv[0]);
+  setlocale (LC_ALL, "");
+  bindtextdomain (PACKAGE, LOCALEDIR);
+  textdomain (PACKAGE);
+
+  atexit (close_stdout);
+
+  flag_append = false;
+
+  while ((optc = getopt_long (argc, argv, "aci:", long_options, NULL)) != -1)
+    {
+      switch (optc)
+        {
+        case 'a':
+          flag_append = true;
+          break;
+
+        case 'c':
+          flag_creat = true;
+          break;
+
+        case 'i':
+          input_stream = xdectoimax (optarg , 0, OPEN_MAX_MAX, "",
+                                     _("invalid input stream number"), 0);
+          break;
+
+        case_GETOPT_HELP_CHAR;
+
+        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+
+        default:
+          usage (EXIT_FAILURE);
+        }
+    }
+
+  if (argc <= optind)
+    {
+      error (0, 0, _("missing operand"));
+      usage (EXIT_FAILURE);
+    }
+
+  if (1 < argc - optind)
+    {
+      error (0, 0, _("extra operand: %s"), quoteaf (argv[optind + 1]));
+      usage (EXIT_FAILURE);
+    }
+
+  bool ok = sink (input_stream, argv[optind]);
+
+  return ok ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/tests/local.mk b/tests/local.mk
index d3cfbcd02..c724c9630 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -359,6 +359,7 @@ all_tests =					\
   tests/misc/shred-size.sh			\
   tests/misc/shuf.sh				\
   tests/misc/shuf-reservoir.sh			\
+  tests/misc/sink.sh				\
   tests/misc/sleep.sh				\
   tests/misc/sort.pl				\
   tests/misc/sort-benchmark-random.sh		\
diff --git a/tests/misc/help-version.sh b/tests/misc/help-version.sh
index 17d4c7032..04ca3432f 100755
--- a/tests/misc/help-version.sh
+++ b/tests/misc/help-version.sh
@@ -195,6 +195,7 @@ logname_setup () { args=--version; }
 nohup_setup () { args=--version; }
 printf_setup () { args=foo; }
 seq_setup () { args=10; }
+sink_setup () { args=$tmp_out; }
 sleep_setup () { args=0; }
 stdbuf_setup () { args="-oL true"; }
 timeout_setup () { args=--version; }
diff --git a/tests/misc/sink.sh b/tests/misc/sink.sh
new file mode 100755
index 000000000..395cbbc29
--- /dev/null
+++ b/tests/misc/sink.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+# test for basic sink functionality.
+
+# Copyright (C) 2021 Free Software Foundation, Inc.
+
+# 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 <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ sink
+
+echo line >sample || framework_failure_
+
+# Simple run.
+sink file <sample >out 2>err || fail=1
+compare sample file || fail=1
+compare /dev/null out || fail=1
+compare /dev/null err || fail=1
+
+# No FILE given.
+returns_ 1 sink <sample >out 2>err || fail=1
+compare /dev/null out || fail=1
+grep 'missing operand' err || { cat err; fail=1; }
+
+# Extra operand.
+returns_ 1 sink file extra <sample >out 2>err || fail=1
+compare /dev/null out || fail=1
+grep 'extra operand' err || { cat err; fail=1; }
+
+# Test -a, --append.
+for o in -a --append; do
+  rm -f file out err || framework_failure_
+
+  # New file: -a does nothing special.
+  sink $o file <sample >out 2>err || fail=1
+  compare sample file || fail=1
+  compare /dev/null out || fail=1
+  compare /dev/null err || fail=1
+
+  # remove out+err.
+  rm -f out err || framework_failure_
+  # prepare file to append.
+  echo survived > file || framework_failure_
+  { echo survived; echo line; } > exp || framework_failure_
+
+  # Test the EEXIST case.
+  sink $o file <sample >out 2>err || fail=1
+  compare exp file || fail=1
+  compare /dev/null out || fail=1
+  compare /dev/null err || fail=1
+done
+rm -f file exp out err || framework_failure_
+
+# Test -c, --create.
+for o in -c --create; do
+  rm -f file out err || framework_failure_
+
+  sink $o file <sample >out 2>err || fail=1
+  compare sample file || fail=1
+  compare /dev/null out || fail=1
+  compare /dev/null err || fail=1
+
+  # keep file, remove out+err.
+  rm -f out err || framework_failure_
+
+  # Test the EEXIST case.
+  returns_ 1 sink $o file <sample >out 2>err || fail=1
+  compare /dev/null out || fail=1
+  grep exist err || fail=1
+
+  # remove file, out+err.
+  rm -f file our err || framework_failure_
+
+  # Test --create with --append: append is a noop.
+  sink $o -a file <sample >out 2>err || fail=1
+  compare sample file || fail=1
+  compare /dev/null out || fail=1
+  compare /dev/null err || fail=1
+done
+rm -f in file out err || framework_failure_
+
+# Test -i, --input-stream.
+for o in -i --input-stream; do
+  # Exercise FD=0 (=stdin).
+  sink $o 0 file <sample >out 2>err || fail=1
+  compare sample file || fail=1
+  compare /dev/null out || fail=1
+  compare /dev/null err || fail=1
+  rm -f file out err || framework_failure_
+
+  # Exercise wit FD=18.
+  echo other >in || framework_failure_
+  sink $o 18 file <in 18<sample >out 2>err || fail=1
+  compare sample file || fail=1
+  compare /dev/null out || fail=1
+  compare /dev/null err || fail=1
+  rm -f in file out err || framework_failure_
+done
+
+# Exercise -i with invalid values: negative or non-numeric.
+returns_ 1 sink -i-1 file <sample >out 2>err || fail=1
+grep 'invalid input stream number' err || { cat err; fail=1; }
+
+returns_ 1 sink --input-stream=A file <sample >out 2>err || fail=1
+grep 'invalid input stream number' err || { cat err; fail=1; }
+
+# Exercise -i with EBADF.
+# FD is closed.
+returns_ 1 sink -i18 file 18<&- >out 2>err || fail=1
+compare /dev/null file || fail=1
+compare /dev/null out || fail=1
+grep 'read failed' err || { cat err; fail=1; }
+rm -f file out err || framework_failure_
+
+# FD is open for writing only.
+returns_ 1 sink -i18 file 18>f >out 2>err || fail=1
+compare /dev/null file || fail=1
+compare /dev/null out || fail=1
+grep 'read failed' err || { cat err; fail=1; }
+rm -f file out err || framework_failure_
+
+# Exercise open's EISDIR.
+returns_ 1 sink . <sample >out 2>err || fail=1
+compare /dev/null out || fail=1
+grep 'open failed' err || { cat err; fail=1; }
+rm -f out err || framework_failure_
+
+# Exercise ENOSPC.
+if test -w /dev/full && test -c /dev/full; then
+  yes | returns_ 1 timeout 10 sink /dev/full >err 2>err || fail=1
+  compare /dev/null out || fail=1
+  grep 'write failed' err || { cat err; fail=1; }
+  rm -f err || framework_failure_
+fi
+
+Exit $fail
-- 
2.30.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-25  4:03                         ` Bernhard Voelker
@ 2021-01-25 11:33                           ` Alejandro Colomar (man-pages)
  2021-01-26  9:08                             ` Alejandro Colomar (man-pages)
  2021-01-27  1:40                           ` Alex Henrie
  2021-03-14  9:44                           ` Alejandro Colomar (man-pages)
  2 siblings, 1 reply; 19+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-01-25 11:33 UTC (permalink / raw)
  To: Bernhard Voelker, Alex Henrie, Otto Moerbeek, Coreutils
  Cc: Fabrice BAUZAC, juli, Jeffrey Walton, freebsd-hackers,
	William Ahern, Roman Czyborra, oshogbo, tech,
	Christian Groessler, linux-api, Michael Kerrisk, ed, Eric Pruitt

On 1/25/21 5:03 AM, Bernhard Voelker wrote:
> On 1/24/21 9:01 PM, Alex Henrie wrote:
>> I am definitely interested. Bernhard Voelker seemed to express
>> interest as well, conditional on -q being added to POSIX first.[1]
> 
> Just to clarify: I'm not as enthusiastic to add that option as it
> may have sounded.
> 
> Let me put it like this: if -q once gets standardized by POSIX,
> then we'd take it over in the GNU tee implementation.
> 
> Let me summarize so far:
> The suggestion is to solve the problem to save some data coming from
> a pipe as a different user.
> There are at least those known solutions:
>    - use > or >> redirection.
>    - use dd(1)
> 
> I have the impression that a home for this feature was searched
> in any tool, and as tee(1) already knew how to write to a file,
> had the "append" feature, and is often used in pipes, it was
> tempting to add it there.
> 
> But looking deeper, --quiet doesn't seem to fit well into 'tee'.
> It even contradicts to the title line in the man page:
>    "read from standard input and write to standard output and files"
> 
> An off-tech argument: ask a local plumber if he'd would ever use
> a tee piece instead of a pipe end piece.  I guess he would only
> if he wouldn't have anything else at hand.

I never knew what 'tee' meant.  That makes sense now.

> 
> A word to the proposed patch: what should happen, if the user does
> not give a file?
>    A | B | tee -q
> The patch just silently ignored that situation which feels wrong.
> 
> Therefore, adding a feature which does not really fit is wrong, and
> contradicts the one-tool-for-one-purpose UNIX philosophy.
> 

Agreed.

> OTOH I understand that there's a little gap in the tool landscape.
> Astonishingly, there doesn't seem to exist a trivial tool to redirect
> from standard input (or any other input file descriptor) to a file.
> I wrote such a little tool in the attached:
> 
>    $ src/sink --help
>    Usage: src/sink [OPTION]... FILE
>    Copy input stream to FILE.
> 
>    Mandatory arguments to long options are mandatory for short options too.
> 
>      -a, --append              append to the given FILE, do not overwrite
>      -c, --create              ensure to create FILE, error if exists
>      -i, --input-stream=FD     read from stream FD instead of standard input
> 
>    The default input stream number FD is 0, representing the standard input.
> 
> This allows not only to copy data from standard input, but from any
> file descriptor open for reading.  It also allows control over
> how the output file will be opened (e.g. with O_CREAT|E_EXCL).
> 
> The OPs case would look like:
> 
>    echo 'foo' | sudo sink /etc/foo
> or
>    echo 'foo' | sudo sink -a /etc/foo  # append.
> or
>    echo 'foo' | sudo sink -c /etc/foo  # ensure creation of the file.
> 
> I'm not sure if this will ever be considered for inclusion -
> I just did it "for fun". ;-)

Tested-by: Alejandro Colomar <alx.manpages@gmail.com>
Reviewed-by: Alejandro Colomar <alx.manpages@gmail.com>

Much better than my patch.  :-)

> 
> Have a nice day,
> Berny
> 

Have a nice day!
Alex


--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-24 12:18                   ` [PATCH v3 (resend)] " Alejandro Colomar
  2021-01-24 16:11                     ` Teran McKinney
  2021-01-24 17:51                     ` Otto Moerbeek
@ 2021-01-25 16:06                     ` Philipp-Joachim Ost
  2 siblings, 0 replies; 19+ messages in thread
From: Philipp-Joachim Ost @ 2021-01-25 16:06 UTC (permalink / raw)
  To: Alejandro Colomar, Bernhard Voelker, Alex Henrie,
	Christian Groessler, Pádraig Brady, Coreutils,
	William Ahern, Erik Auerswald, Eric Pruitt, Jeffrey Walton
  Cc: Michael Kerrisk, Fabrice BAUZAC, tech, freebsd-hackers,
	linux-api, juli, ed, oshogbo

Am 24.01.2021 um 13:18 schrieb Alejandro Colomar:
> This is useful for using tee to just write to a file,
> at the end of a pipeline,
> without having to redirect to /dev/null
> 
> Example:
> 
> echo 'foo' | sudo tee -q /etc/foo;
> 
> is equivalent to the old (and ugly)
> 
> echo 'foo' | sudo tee /etc/foo >/dev/null;

Why don't you just do

echo foo > /etc/foo

or

sudo sh -c 'echo foo > /etc/foo' ?

I don't normally use sudo, so there might be some better way of using it.

Kind regards,
Philipp

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-25 11:33                           ` Alejandro Colomar (man-pages)
@ 2021-01-26  9:08                             ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 19+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-01-26  9:08 UTC (permalink / raw)
  To: Bernhard Voelker, Coreutils
  Cc: Fabrice BAUZAC, Otto Moerbeek, Alex Henrie, juli, Jeffrey Walton,
	freebsd-hackers, William Ahern, Roman Czyborra, oshogbo, tech,
	Christian Groessler, linux-api, Michael Kerrisk, ed, Eric Pruitt

Hi Berny,

On 1/25/21 12:33 PM, Alejandro Colomar (man-pages) wrote:
> On 1/25/21 5:03 AM, Bernhard Voelker wrote:
>> On 1/24/21 9:01 PM, Alex Henrie wrote:
>>> I am definitely interested. Bernhard Voelker seemed to express
>>> interest as well, conditional on -q being added to POSIX first.[1]
>>
>> Just to clarify: I'm not as enthusiastic to add that option as it
>> may have sounded.
>>
>> Let me put it like this: if -q once gets standardized by POSIX,
>> then we'd take it over in the GNU tee implementation.
>>
>> Let me summarize so far:
>> The suggestion is to solve the problem to save some data coming from
>> a pipe as a different user.
>> There are at least those known solutions:
>>    - use > or >> redirection.
>>    - use dd(1)
>>
>> I have the impression that a home for this feature was searched
>> in any tool, and as tee(1) already knew how to write to a file,
>> had the "append" feature, and is often used in pipes, it was
>> tempting to add it there.
>>
>> But looking deeper, --quiet doesn't seem to fit well into 'tee'.
>> It even contradicts to the title line in the man page:
>>    "read from standard input and write to standard output and files"
>>
>> An off-tech argument: ask a local plumber if he'd would ever use
>> a tee piece instead of a pipe end piece.  I guess he would only
>> if he wouldn't have anything else at hand.
> 
> I never knew what 'tee' meant.  That makes sense now.
> 
>>
>> A word to the proposed patch: what should happen, if the user does
>> not give a file?
>>    A | B | tee -q
>> The patch just silently ignored that situation which feels wrong.
>>
>> Therefore, adding a feature which does not really fit is wrong, and
>> contradicts the one-tool-for-one-purpose UNIX philosophy.
>>
> 
> Agreed.
> 
>> OTOH I understand that there's a little gap in the tool landscape.
>> Astonishingly, there doesn't seem to exist a trivial tool to redirect
>> from standard input (or any other input file descriptor) to a file.
>> I wrote such a little tool in the attached:
>>
>>    $ src/sink --help
>>    Usage: src/sink [OPTION]... FILE
>>    Copy input stream to FILE.
>>
>>    Mandatory arguments to long options are mandatory for short options 
>> too.
>>
>>      -a, --append              append to the given FILE, do not overwrite
>>      -c, --create              ensure to create FILE, error if exists
>>      -i, --input-stream=FD     read from stream FD instead of standard 
>> input


On second thought, this program does two things: read any FD, and write 
to file.  I think it should be limited to writing to a file from stdin.

If you think there's a need for reading FDs other than 0, you might as 
well want to pipe that information you're reading from them to filter it 
with another tool, and this program doesn't allow you to do that, as 
it's a sink.

So, I would remove '-i, --input-stream'.  (And if you think it's 
missing, maybe write a program to read from any FD and write to stdout.)

Regards,

Alex


>>
>>    The default input stream number FD is 0, representing the standard 
>> input.
>>
>> This allows not only to copy data from standard input, but from any
>> file descriptor open for reading.  It also allows control over
>> how the output file will be opened (e.g. with O_CREAT|E_EXCL).
>>
>> The OPs case would look like:
>>
>>    echo 'foo' | sudo sink /etc/foo
>> or
>>    echo 'foo' | sudo sink -a /etc/foo  # append.
>> or
>>    echo 'foo' | sudo sink -c /etc/foo  # ensure creation of the file.
>>
>> I'm not sure if this will ever be considered for inclusion -
>> I just did it "for fun". ;-)
> 
> Tested-by: Alejandro Colomar <alx.manpages@gmail.com>
> Reviewed-by: Alejandro Colomar <alx.manpages@gmail.com>
> 
> Much better than my patch.  :-)
> 
>>
>> Have a nice day,
>> Berny
>>
> 
> Have a nice day!
> Alex
> 
> 
> -- 
> Alejandro Colomar
> Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
> http://www.alejandro-colomar.es/


-- 
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-25  4:03                         ` Bernhard Voelker
  2021-01-25 11:33                           ` Alejandro Colomar (man-pages)
@ 2021-01-27  1:40                           ` Alex Henrie
  2021-03-14  9:44                           ` Alejandro Colomar (man-pages)
  2 siblings, 0 replies; 19+ messages in thread
From: Alex Henrie @ 2021-01-27  1:40 UTC (permalink / raw)
  To: Bernhard Voelker
  Cc: Otto Moerbeek, Coreutils, Alejandro Colomar, Fabrice BAUZAC,
	Juli Mallett, Jeffrey Walton, freebsd-hackers, William Ahern,
	Roman Czyborra, oshogbo, tech, Christian Groessler, linux-api,
	Michael Kerrisk, Ed Schouten, Eric Pruitt

On Sun, Jan 24, 2021 at 9:04 PM Bernhard Voelker
<mail@bernhard-voelker.de> wrote:
>
> An off-tech argument: ask a local plumber if he'd would ever use
> a tee piece instead of a pipe end piece.  I guess he would only
> if he wouldn't have anything else at hand.

According to POSIX, tee writes to "zero or more files."[1] So the
"local plumber" analogy already doesn't hold, because a plumber would
never put in a tee and then immediately cap it off so that the flow
can only go to one place, but commands like `echo foo | tee | tee |
tee` are already explicitly allowed.

> A word to the proposed patch: what should happen, if the user does
> not give a file?
>   A | B | tee -q
> The patch just silently ignored that situation which feels wrong.

Personally, I like the idea of only having to type `echo foo | tee -q`
instead of `echo foo > /dev/null`, so I think the patch indeed does
the right thing in that case.

-Alex

[1] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/tee.html

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-01-25  4:03                         ` Bernhard Voelker
  2021-01-25 11:33                           ` Alejandro Colomar (man-pages)
  2021-01-27  1:40                           ` Alex Henrie
@ 2021-03-14  9:44                           ` Alejandro Colomar (man-pages)
  2021-03-15 17:42                             ` Alex Henrie
  2 siblings, 1 reply; 19+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-03-14  9:44 UTC (permalink / raw)
  To: Bernhard Voelker, Alex Henrie, Otto Moerbeek, Coreutils
  Cc: Fabrice BAUZAC, juli, Jeffrey Walton, freebsd-hackers,
	William Ahern, Roman Czyborra, oshogbo, tech,
	Christian Groessler, linux-api, Michael Kerrisk, ed, Eric Pruitt



On 1/25/21 5:03 AM, Bernhard Voelker wrote:
> OTOH I understand that there's a little gap in the tool landscape.
> Astonishingly, there doesn't seem to exist a trivial tool to redirect
> from standard input (or any other input file descriptor) to a file.
> I wrote such a little tool in the attached:
> 
>    $ src/sink --help
>    Usage: src/sink [OPTION]... FILE
>    Copy input stream to FILE.
> 
>    Mandatory arguments to long options are mandatory for short options too.
> 
>      -a, --append              append to the given FILE, do not overwrite
>      -c, --create              ensure to create FILE, error if exists
>      -i, --input-stream=FD     read from stream FD instead of standard input
> 
>    The default input stream number FD is 0, representing the standard input.
> 
> This allows not only to copy data from standard input, but from any
> file descriptor open for reading.  It also allows control over
> how the output file will be opened (e.g. with O_CREAT|E_EXCL).
> 
> The OPs case would look like:
> 
>    echo 'foo' | sudo sink /etc/foo
> or
>    echo 'foo' | sudo sink -a /etc/foo  # append.
> or
>    echo 'foo' | sudo sink -c /etc/foo  # ensure creation of the file.
> 
> I'm not sure if this will ever be considered for inclusion -
> I just did it "for fun". ;-)
> 
> Have a nice day,
> Berny
> 

By chance, I just found out that there is a tool very similar to 'sink' 
in moreutils [1].  It's called 'sponge'.

[1]: <https://joeyh.name/code/moreutils/>

So this feature already exists, and therefore I drop my patches.

Cheers,

Alex

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-03-14  9:44                           ` Alejandro Colomar (man-pages)
@ 2021-03-15 17:42                             ` Alex Henrie
  2021-03-15 20:20                               ` Alex Henrie
  0 siblings, 1 reply; 19+ messages in thread
From: Alex Henrie @ 2021-03-15 17:42 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: Bernhard Voelker, Otto Moerbeek, Coreutils, Fabrice BAUZAC,
	Juli Mallett, Jeffrey Walton, freebsd-hackers, William Ahern,
	Roman Czyborra, oshogbo, tech, Christian Groessler, linux-api,
	Michael Kerrisk, Ed Schouten, Eric Pruitt

On Sun, Mar 14, 2021 at 3:44 AM Alejandro Colomar (man-pages)
<alx.manpages@gmail.com> wrote:
>
> On 1/25/21 5:03 AM, Bernhard Voelker wrote:
> > OTOH I understand that there's a little gap in the tool landscape.
> > Astonishingly, there doesn't seem to exist a trivial tool to redirect
> > from standard input (or any other input file descriptor) to a file.
> > I wrote such a little tool in the attached:
> >
> >    $ src/sink --help
> >    Usage: src/sink [OPTION]... FILE
> >    Copy input stream to FILE.
> >
> >    Mandatory arguments to long options are mandatory for short options too.
> >
> >      -a, --append              append to the given FILE, do not overwrite
> >      -c, --create              ensure to create FILE, error if exists
> >      -i, --input-stream=FD     read from stream FD instead of standard input
> >
> >    The default input stream number FD is 0, representing the standard input.
> >
> > This allows not only to copy data from standard input, but from any
> > file descriptor open for reading.  It also allows control over
> > how the output file will be opened (e.g. with O_CREAT|E_EXCL).
> >
> > The OPs case would look like:
> >
> >    echo 'foo' | sudo sink /etc/foo
> > or
> >    echo 'foo' | sudo sink -a /etc/foo  # append.
> > or
> >    echo 'foo' | sudo sink -c /etc/foo  # ensure creation of the file.
> >
> > I'm not sure if this will ever be considered for inclusion -
> > I just did it "for fun". ;-)
> >
> > Have a nice day,
> > Berny
> >
>
> By chance, I just found out that there is a tool very similar to 'sink'
> in moreutils [1].  It's called 'sponge'.
>
> [1]: <https://joeyh.name/code/moreutils/>
>
> So this feature already exists, and therefore I drop my patches.
>
> Cheers,
>
> Alex

Interesting, thanks for sharing. There's still no `sponge -q` option
though--it always writes either to a file or to standard output.

-Alex

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v3 (resend)] tee: Add -q, --quiet, --silent option to not write to stdout
  2021-03-15 17:42                             ` Alex Henrie
@ 2021-03-15 20:20                               ` Alex Henrie
  0 siblings, 0 replies; 19+ messages in thread
From: Alex Henrie @ 2021-03-15 20:20 UTC (permalink / raw)
  To: Alejandro Colomar (man-pages)
  Cc: Bernhard Voelker, Otto Moerbeek, Coreutils, Fabrice BAUZAC,
	Juli Mallett, Jeffrey Walton, freebsd-hackers, William Ahern,
	Roman Czyborra, oshogbo, tech, Christian Groessler, linux-api,
	Michael Kerrisk, Ed Schouten, Eric Pruitt

On Mon, Mar 15, 2021 at 11:42 AM Alex Henrie <alexhenrie24@gmail.com> wrote:
>
> On Sun, Mar 14, 2021 at 3:44 AM Alejandro Colomar (man-pages)
> <alx.manpages@gmail.com> wrote:
> >
> > On 1/25/21 5:03 AM, Bernhard Voelker wrote:
> > > OTOH I understand that there's a little gap in the tool landscape.
> > > Astonishingly, there doesn't seem to exist a trivial tool to redirect
> > > from standard input (or any other input file descriptor) to a file.
> > > I wrote such a little tool in the attached:
> > >
> > >    $ src/sink --help
> > >    Usage: src/sink [OPTION]... FILE
> > >    Copy input stream to FILE.
> > >
> > >    Mandatory arguments to long options are mandatory for short options too.
> > >
> > >      -a, --append              append to the given FILE, do not overwrite
> > >      -c, --create              ensure to create FILE, error if exists
> > >      -i, --input-stream=FD     read from stream FD instead of standard input
> > >
> > >    The default input stream number FD is 0, representing the standard input.
> > >
> > > This allows not only to copy data from standard input, but from any
> > > file descriptor open for reading.  It also allows control over
> > > how the output file will be opened (e.g. with O_CREAT|E_EXCL).
> > >
> > > The OPs case would look like:
> > >
> > >    echo 'foo' | sudo sink /etc/foo
> > > or
> > >    echo 'foo' | sudo sink -a /etc/foo  # append.
> > > or
> > >    echo 'foo' | sudo sink -c /etc/foo  # ensure creation of the file.
> > >
> > > I'm not sure if this will ever be considered for inclusion -
> > > I just did it "for fun". ;-)
> > >
> > > Have a nice day,
> > > Berny
> > >
> >
> > By chance, I just found out that there is a tool very similar to 'sink'
> > in moreutils [1].  It's called 'sponge'.
> >
> > [1]: <https://joeyh.name/code/moreutils/>
> >
> > So this feature already exists, and therefore I drop my patches.
> >
> > Cheers,
> >
> > Alex
>
> Interesting, thanks for sharing. There's still no `sponge -q` option
> though--it always writes either to a file or to standard output.
>
> -Alex

Actually, it looks like `pee` (also from moreutils) can be used for
throwing input into the void. So between `sponge` and `pee`, I think
all the use cases are covered!

-Alex

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2021-03-15 20:21 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20210121131735.317701-1-alx.manpages@gmail.com>
     [not found] ` <8aa1d0b4-d2ec-7d18-120b-cae59708767c@draigBrady.com>
     [not found]   ` <424b9fb9-c740-1a2f-bd79-0b4035104698@gmail.com>
     [not found]     ` <e1a3b389-b808-92db-258d-85b60748b4dc@bernhard-voelker.de>
     [not found]       ` <06fb3df3-a956-3ec1-eadb-82fd89ec62d5@gmail.com>
     [not found]         ` <af2fb24a-a03a-35ef-c86e-545844b61a8d@groessler.org>
     [not found]           ` <CAMMLpeRSh5HKi=sJV7y=pav26EzzP-yEe0+Dgp_=mtBUhtFvaQ@mail.gmail.com>
     [not found]             ` <3bb6a134-c477-116c-182d-d6e24dc342e0@bernhard-voelker.de>
     [not found]               ` <f78ec1a9-f07f-de20-26cc-4be254e3e921@gmail.com>
2021-01-21 22:49                 ` [PATCH] tee: Add -q, --quiet option to not write to stdout Alejandro Colomar (man-pages)
2021-01-21 23:12                   ` [PATCH v2] tee: Add -q, --quiet, --silent " Alejandro Colomar
2021-01-22 18:25                     ` Alejandro Colomar (man-pages)
2021-01-23 14:53                   ` [PATCH] " Alejandro Colomar
2021-01-24 12:18                   ` [PATCH v3 (resend)] " Alejandro Colomar
2021-01-24 16:11                     ` Teran McKinney
2021-01-24 16:22                       ` Alejandro Colomar (man-pages)
2021-01-24 17:51                     ` Otto Moerbeek
2021-01-24 17:58                       ` Theo de Raadt
2021-01-24 20:01                       ` Alex Henrie
2021-01-24 20:22                         ` Otto Moerbeek
2021-01-25  4:03                         ` Bernhard Voelker
2021-01-25 11:33                           ` Alejandro Colomar (man-pages)
2021-01-26  9:08                             ` Alejandro Colomar (man-pages)
2021-01-27  1:40                           ` Alex Henrie
2021-03-14  9:44                           ` Alejandro Colomar (man-pages)
2021-03-15 17:42                             ` Alex Henrie
2021-03-15 20:20                               ` Alex Henrie
2021-01-25 16:06                     ` Philipp-Joachim Ost

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.