[RndTbl] Shell exec(2) help?

Adam Thompson athompso at athompso.net
Tue Jun 30 11:05:13 CDT 2020


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


More information about the Roundtable mailing list