help-bash
[Top][All Lists]
Advanced

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

Re: [Help-bash] Is there a way to make unamed pipe nonexist upon error?


From: Stephane Chazelas
Subject: Re: [Help-bash] Is there a way to make unamed pipe nonexist upon error?
Date: Thu, 26 Sep 2019 15:44:01 +0100
User-agent: NeoMutt/20171215

2019-09-26 08:31:32 -0500, Peng Yu:
> > What you can do is something like:
> >
> > gawk -v f=<(cat nosuchfile.txt || echo FAILED) '
> >   BEGIN {
> >     RS="^$"
> >     getline content < f
> >     if (content ~ /FAILED/) {
> >       print "failed" > "/dev/stderr"
> >       exit(1)
> >     }
> >   }'
> 
> https://www.iterm2.com/documentation-escape-codes.html
> 
> iterm2 has some proprietary escape codes. Are there any proprietary
> escape codes that are appropriate for this purpose to signal a filed
> pipe?

pipes have nothing to do with terminals, they are a
communication device between two processes. The data you send at
one end is read at the other end. Some reader process could want
to treat some sequence of byte as special. That's what we do
here with the "FAILED" sequence which we treat as meaning
failure.

pseudo-terminal devices are another form of communication
device, which can be used for instance for a process to interact
with a terminal emulator application. The terminal emulator
translates what it reads from the reading end of that
pseudo-pipe to things to display on its emulated screen. It
interprets some byte sequence specially (like "\e[1m" to enable
a bold attribute).

> 
> > In theory, instead of echo FAILED, you could add code that tries
> > to identify the process(es) that are at the other end of the
> > pipe and kill the one that is running awk if any. On Linux and
> > with recent versions of lsof, that could be done with something
> > like:
> >
> > gawk -v f=<(
> >   cat nosuchfile || {
> >     re=$'\nnpipe[^\n]*[ ,]([[:digit:]]+),gawk,[[:digit:]]+r'
> >     [[ ! $(lsof -Fn -ad3 -E -p "$BASHPID") =~ $re ]] ||
> >       kill "${BASH_REMATCH[1]}"
> >   } 3>&1) '
> >   BEGIN {
> >     RS="^$"
> >     r = getline content < f
> >     print r, content
> >   }'
> 
> I got an error in lsof. Which version of lsof do you use? My OS is Mac OS X.

I did say "On Linux" above. That will only work on Linux AFAIK.
That feature was added in 4.89 in 2015

[...]
> > CMD='cat nosuchfile' gawk '
> >   BEGIN {
> >     RS="^$"
> >     r = ENVIRON["CMD"] | getline output
> >     status = close(ENVIRON["CMD"])
> >     print r, status, output
> >   }'
> 
> In my case, CMD is a bash function instead of an external command.
> Since a bash function can not be easily called by awk (otherwise, it
> becomes too complicated). So I can not use this approach.

FWIW, awk will interpret that command line using /bin/sh and on
macOS, /bin/sh happens to be bash, and bash happens to be able
to export functions via the environment.

-- 
Stephane




reply via email to

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