[RndTbl] Shell exec(2) help?

Troy Denton trdenton at gmail.com
Tue Jun 30 11:27:57 CDT 2020


I think you are correct on the RHS of the pipe.  If you are not adverse to
bash, this appears to work as expected:


#!/bin/bash

echo "i am doing something useful"
sleep 3 &
wait
exec bash <(curl -s $URL/test.sh)


if bash is a no-go, (simply needed for the <() operation), you may just
need to download a temporary file and e.g. 'exec sh /tmp/script.sh'

I think the crux of it is the exec replaces the current process with
whatever you provide it.  But on the RHS of the pipe, that current process
is a subshell

On Tue, Jun 30, 2020 at 11:06 AM Adam Thompson <athompso at athompso.net>
wrote:

> Even that doesn't quite work:
>
> root at bgpmirror:~# pstree -g 3 -w -s screen
> ─┬= 00001 root /sbin/init
>   └─┬= 04264 root sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
> (sshd)
>     └─┬= 20865 root sshd: root at ttyp0,ttyp2,ttyp1 (sshd)
>       └─┬= 73703 root -ksh (ksh)
>         └─┬= 59765 root screen -U -q -i -fa
>           └─┬= 01077 root SCREEN -U -q -i -fa (screen)
>             └─┬= 03339 root /bin/ksh
>               └─┬─ 93663 root sh -c curl -s
> https://lg.merlin.ca/ping/go.sh | sh
>                 └─┬─ 87697 root sh -c curl -s
> https://lg.merlin.ca/ping/go.sh | sh
>                   └─┬─ 25186 root sh -c curl -s
> https://lg.merlin.ca/ping/go.sh | sh
>                     └─┬─ 85474 root sh
>                       └─── 11715 root sleep 60
>
> Argh.
>
> FYI, I also tried "exec ( curl ... | sh)" which did not work, it
> produced an error instead.
>
> A loop isn't suitable, because I want to be able to pick up any changes
> to the script on the fly - that's why I'm doing it this way in the first
> place.
>
> -Adam
>
>
> On 2020-06-30 10:36, Gilbert E. Detillieux wrote:
> > Adam,
> >
> > I think you're correct in your assumption about the problem being with
> > the pipe.  IIRC, the shell spawns a child to manage each pipeline, so
> > that it can properly handle redirects, signals, etc., as it sets up
> > the pipeline. In the case of the original Bourne shell, the child
> > shell process then does an exec on the last binary in the pipeline, so
> > its exit status is used as the exit status of the entire pipeline.
> >
> > So, the explicit exec you are doing has no real effect, as it's
> > happening in a child process, and not the parent shell.
> >
> > Likely also, YMMV depending on which specific shell you use.
> >
> > Not sure if this would work better?...
> >
> > exec sh -c "curl -s $URL/go.sh | sh"
> >
> > You still have parent & child shell processes, but I'm not sure if
> > they'll exit differently.  Maybe you'd need to background the pipeline
> > to allow the parent shell to exit, and the background pipeline to take
> > over?
> >
> > Or just do a loop, as Rob suggested.  :)
> >
> > Gilbert
> >
> > On 2020-06-30 10:16 a.m., Adam Thompson wrote:
> >> I've written a shell script that redownloads itself and re-executes
> >> itself, but I'm not quite seeing the behaviour I'd expect out of "exec
> >> sh".  Instead of one process, I get an infinite progression of shells
> >> that finally blows up when I hit ulimits.
> >>
> >> The script:
> >>
> >> ===BOF===
> >> curl -s $URL/targets \
> >> | while read TGTNAME TGTIP ; do
> >>      (
> >>          echo -n "."
> >>
> >>          mtr \
> >>              --interval 0.1 \
> >>              --gracetime 1 \
> >>              --timeout 1 \
> >>              --report-wide \
> >>              --report-cycles 600 \
> >>              --show-ips \
> >>              --aslookup \
> >>              --no-dns \
> >>              ${TGTIP} \
> >>          | awk -f parse.awk -v TGT=${TGTNAME}  \
> >>          | psql -q -b -h $PGHOST -U $PGUSER $PGDB
> >>      ) &
> >>     wait &
> >> done
> >>
> >> # start all over again
> >> sleep 60 &
> >> wait
> >> curl -s $URL/go.sh | exec sh
> >> ===EOF===
> >>
> >> The key items are the backgrounding of mtr/awk/psql, which appears to
> >> work properly - there's 12 lines in "targets" and I only see 12
> >> mtr/awk/psql process groups at a time - the sleeping + waiting (which
> >> theoretically reaps all children and grandchildren, I think) and the
> >> final "exec".
> >>
> >> Except instead of exec'ing, I run an infinite sequence of shells, each
> >> one a child of the previous.  E.g. from pstree(1):
> >>
> >> # pstree -lp 1628
> >>
> screen(1628)─┬─bash(1629)───sh(12707)───sh(12854)───sh(12986)───sh(13154)───sh(13309)───sh(13444)───sh(13579)───sh(13709)───sh(13842)───sh(13979)───sh(14101)───sh(14242)───sh(14396)───sh(14530)───sh(14655)───sh(14795)───sh(14935)───sh(15076)───sh(15203)───sh(15353)───sh(15490)───sh(15624)───sh(15753)───sh(15891)───sh(16023)───sh(16154)───sh(16282)───sh(16418)───sh(16551)───sh(16696)───sh(16842)───sh(16975)───sh(17112)───sh(17241)───sh(17388)───sh(17522)───sh(17664)───sh(17824)───sh(17956)───sh(18096)───sh(18233)───sleep(18279)
>
> >> I think the problem has something to do with the fact the final exec
> >> is on the RHS of a pipe, and thus is executing inside a subshell, but
> >> how do I fix this?
> >>
> >> Thanks,
> >> -Adam
> _______________________________________________
> Roundtable mailing list
> Roundtable at muug.ca
> https://muug.ca/mailman/listinfo/roundtable
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://muug.ca/pipermail/roundtable/attachments/20200630/bf743a3e/attachment-0001.htm>


More information about the Roundtable mailing list