Even that doesn't quite work:
root@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@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