[Tfug] Fwd: Properly terminating a shell script after using X Windows

Bexley Hall bexley401 at yahoo.com
Thu Jan 31 19:58:21 MST 2013


Hi John,

On 1/31/2013 7:24 PM, John Gruenenfelder wrote:
> On Mon, Jan 28, 2013 at 11:15 AM, Bexley Hall<bexley401 at yahoo.com>  wrote:
>>> On the other hand, attempting to *sense* when to exit would be the
>>> more general solution, though likely harder to make 100% reliable.  I
>>> originally mentioned that the script could perform checks to see if X
>>> was still running and/or if the running user was still logged in and
>>> act accordingly.  This could still get complicated easily, but I think
>>> I could add a configuration option that names the X process.  As you
>>> also noted, 'X' is often a link to the actual X server.  More than
>>> that, it is often even a hard link.  I know on my system, and
>>> presumably most all Debian systems, the process as found with 'ps' is
>>> called simply 'X'.  That should make a good default and be easy to
>>> check for (I think).
>>
>> I.e., what you want is for the demise of X -- as an ANCESTOR of your
>> script -- to bring about the orderly termination of your script as
>> well!  Regardless of how (*under* X) your script was started.
>>
>> [Note this assumes you aren't going the "service oriented" direction
>> I mentioned previously]
>>
>> So, I'm suggesting your script just watches to see when it's parent
>> dies!  And, count on X (or whatever agent acting on X's behalf) to
>> kill that process as a consequence of it's (X's) termination.
>>
>> E.g., if X dies, whatever invoked your script also dies (so your
>> script just watches for the invoker's demise).  Similarly, if
>> the user has *manually* invoked your script from some shell, then
>> when *that* shell dies, you die as well!
>>
>> [There are cases where this would not be desirable.  We'll choose
>> to ignore those!  :>  ]
>>
>> So, what your script does is watch for it's PPID to die!  Then,
>> accompanies it!!
>>
>> You can do this by noting the PPID when you are invoked (PPID=$$).
>> Then, explicitly watch to verify that process is still active
>> (e.g., ps -p $PPID).
>
> Uh huh, uh huh...  Oh.  Ohhhhhhhhhhhhh!  :)
> *Now* I get it.  In the last email I think you mentioned the PPID only
> once and I thought it was a typo.  Oops.

Yes, sorry -- I should have written a little scriptlet and let you
but and paste it to less ambiguously make my point.  :<

> But, now I understand.  Yes, this is an excellent suggestion.  It is
> completely independent of the method by which the user executes the
> script and shouldn't have lots of nasty corner cases.  I'm going to
> test this right away, but I don't expect any troubles.

Just pick a shell that you *know* will be available "everywhere".

>> But, for long running processes, this creates a hazard -- given
>> enough time, the pid can end up being reused.  So, you'd have
>> to verify that the process having that $PPID was *actually* the
>> process that started you.
>>
>> [Similarly, if your process sleeps for a long time, your parent can
>> die and pids wrap around before your wake up.  So, it is conceivable
>> (though not likely!) that you will never "see" it as being "dead"]
>
> I guess it's worth checking for this, but given the available range of
> PIDs I think this will be an extremely unlikely event.

By watching the PPID, you let the OS deal with this hazard instead
of having to worry about it yourself!  (I.e., the OS adjusts the
process's PPID "immediately" when these conditions occur)

>> I *think* you can exploit a hack in how PPIDs are handled to
>> implement a "glitch catcher" of sorts.  (i.e., to see the death
>> of your parent even if it's pid is reused faster than the blink
>> of your eye).
>>
>> Watch for the PPID of your *current* process to become '1'
>> (i.e., that of init(1)).  Your process *must* (always) have
>> a declared "parent".  So, the case where the parent dies
>> before the child is handled by the PPID being set to that of
>> init (since init ALWAYS is running).
>>
>> I'm at a Windows machine, presently, so I can't verify any of this
>> (As I so dreaded hearing:  "exercise left for the student"  :>  )
>
> The nice thing about using this method is that it should catch all of
> the situations, not just the PID reuse case.  Regardless of how the
> user chooses to launch the script - session manager,
> .xsession/.xinitrc, GNOME autostart, xterm - all will exit gracefully
> or die when the user leaves X so I *think* this should effectively
> never leave the script running in the background endlessly.

The biggest problem with this approach is that a user *can't*
start your script in an X session (or even a regular console login
session), move it to the background and then "logout" and hope that
your script keeps running (i.e., if it is just being used to fetch
imagery).  Once the "ancestor" process dies, your script will
kill itself!

[I *think* you could work around this by starting some *other* shell,
moving *that* to the background and then starting your script from
within that (?)]

>> Again, I would move the "gathering" activity to a service that
>> runs "always" -- though possibly with different update frequencies
>> so it's not wasting CPU needlessly when no one is logged in (yet
>> always has some "reasonably current" images on hand).
>>
>> [I am obsessed with "services"... I try to make everything
>> resemble a service in my designs!]
>
> Certainly the more elegant solution, I suppose, but I really think it
> is overkill in this particular situation.  The odds are very good that
> only one user will ever be running Xplanet and/or this script at any
> given time on a given system.  Because of this, I think the benefits
> of making the data/image gathering a service aren't that helpful.

Understood.  Note that I wasn't kidding when I said "obsessed"!  :<

> Also, for the sake of the various download servers, there is no reason
> to hit them`when nobody is actually going to look at the data just
> gathered.  That's why I have always had these events occur when the
> script is run and just before creation of the first wallpaper.
>
> Besides, if this is something a user really wants then they can always
> create an entry in their user crontab file, right?

Yes.  Though I don't know the constraints that would have to be
placed on it to ensure you don't end up with multiple instances
running (e.g., if the next one starts up before the previous
one has finished)

>> IMO, it's desirable for the costs of a particular "service"
>> (application) to be born (insofar as possible) by that service
>> itself.  The developer (of the service) knows far more about it
>> than the *consumer* so it makes for more reliable implementations
>> when the developer bears the cost of "getting things right"
>> (instead of hoping the user/consumer does!)
>
> That's true, although in the case of this potential "service" most of
> what it does is just downloading of the latest data: the current
> (every 12 hours) cloud map, and TLE files from Celestrak for any
> enabled artificial satellites.  The TLE files then undergo some very
> minimal processing to generate the file Xplanet needs.
>
> If configured to do so, a helper program called TotalMarker is run to
> grab some other data sets, namely current storms (anything the size of
> a tropical depression or larger, I think), locations of the most
> recent earthquakes, and locations of any active volcanoes (this list
> changes quite infrequently).  Unfortunately, the developer of
> TotalMarker seems to have completely vanished.  I checked all over his
> website for the program but there is zero information giving his name
> or the license TotalMarker is released under.

You might try looking for an earlier release (The Way Back Machine comes
to mind) and hope you can grep a name from that...

> Also, the "program" is actually just compiled Perl and his site does
> state that he has no intention of releasing the source.  I would like
> to eventually figure out what the sources are he uses to get this data
> are so I can re-implement it in something open (probably more Bourne
> shell functions).
>
> Anyway, the only real choice here, after the user has configured
> xplanet-settings.sh to their liking, is one of timing.  If the user
> can't get that right then they probably will have trouble with basic
> usage of Xplanet...

Don't invest much time "idiot proofing" as there are some very
determined idiots out there!

I'd be curious as to what cases this approach *fails* to address
(i.e., when the process persists beyond it's parent(s)' lifetime
and or dies prematurely).  I'm not a "shell hacker" and tend to
just poke around until things "sort of work" when I write scripts
so it is possible that I've missed a whole range of scenarios
that don't work right...  :(




More information about the tfug mailing list