coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: pipes that write to a file


From: Nikolay Nechaev
Subject: Re: pipes that write to a file
Date: Sun, 27 Jun 2021 17:15:04 +0300

Hello! In bash there already is a way to do what you want to do (although, not
exactly in a way you're trying to do it). Not sure, how elegant this is
(actually, it doesn't look pretty), but here's how I'd do it:


#!/bin/bash

function prog1()
{
        sed 's/a/b/g'
}

function prog2()
{
        tee
}

function prog3()
{
        # The command, for which we want to inspect the exit code.
        # Uncomment `false` below to make it fail

        tee

        #false
}

echo aaa > f

prog1 < f | prog2 | (prog3 && echo 1>&2 ok || echo 1>&2 failed) | sponge f


When running this, you will see "ok" in the terminal, if the `#false` line is
commented, and "failed" instead, if you uncomment it.

There, however, seems to be no such feature in the standard sh shell

-- 
Best wishes,
Nikolay Nechaev

On Sunday, 27 June 2021 03:13:59 MSK Bruno Haible wrote:
> Hi,
> 
> 'envsubst' is a small program, part of GNU gettext, that is meant to be used
> within pipes (it reads from stdin and writes to stdout).
> 
> Someone proposes to add an --in-place option so that it would read from a
> file and write its output to the same file. [1]
> 
> However, this would not cover all use-cases. People often use 'envsubst'
> and other commands, together, in a pipe, and want the output to overwrite
> the input file.
> 
> So, people come to recommend the 'sponge' program from moreutils [2]:
> 
>    prog1 < FILE | prog2 | prog3 | sponge FILE
> 
> But this program has the drawback that, requiring another step in the
> pipeline, the exit code of the previous command gets lost. While
> 
>    prog1 < FILE | prog2 | prog3 > $tmpfile
>    mv $tmpfile FILE
> 
> allows logic that inspects the exit code prog3,
> 
>    prog1 < FILE | prog2 | prog3 | sponge FILE
> 
> does not.
> 
> What is the right solution?
> 
> - The code that uses a temporary file [3] is quite cumbersome to write,
>   and is inefficient if the data size is large (since the temporary file
>   will live on a different partition).
> - I understand that an 'inplace' program has been rejected [4].
> 
> How about adding a  -o FILE / --output FILE  to the program prog3
> ('envsubst' in my case, but 'cat' and other programs would also be
> candidates for it), that creates a new temporary file in the same
> directory as FILE and moves it to FILE when done? This would provide
> for an atomic replacement. The Gnulib module 'supersede' would
> implement most of this logic; it is already used by GNU msgfmt's '-o'
> option.
> 
> In other words, move the 'sponge' logic into the last step of the pipe.
> 
> Or should the shells be adapted so that people can write
> 
>    prog1 < FILE | prog2 | prog3 >+ FILE
> 
> and that operator '>+' writes to FILE but only after the pipe has completed?
> 
> Bruno
> 
> [1] https://savannah.gnu.org/bugs/?60807
> [2] 
> https://serverfault.com/questions/135507/linux-how-to-use-a-file-as-input-and-output-at-the-same-time
> [3] https://lists.gnu.org/archive/html/bug-coreutils/2009-03/msg00321.html
> [4] https://lists.gnu.org/archive/html/bug-coreutils/2012-11/msg00184.html
> 
> 
> 







reply via email to

[Prev in Thread] Current Thread [Next in Thread]