tech-userlevel archive

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

Re: Redoing the code in /bin/sh to handle the issues in PR bin/48875



    Date:        Fri, 17 Aug 2018 11:37:18 -0500
    From:        "J. Lewis Muir" <jlmuir%imca-cat.org@localhost>
    Message-ID:  <20180817163717.GA21030%tuna.imca.aps.anl.gov@localhost>

  | I think this sentence would read better if it used the same verb tense

Thanks, that is the kind of improvement I was looking for (since I don't
often even think of such issues...) and I will change it as you suggest.

  | When I first read this, I didn't even know a command inside a "$()" could be
  | terminated with an "&" to cause it to execute in the background in a
  | sub-shell.

Any shell code can go in a command substitution, as it can almost anywhere
else that any commands are permitted -- people are sometiimes surprised when
they see, for the first time, a "while" statement, where the whole (long) loop is in
the "test" part of the while, and the body of the loop contains nothing at all, or 
an "if" statement, where the condition is some other compound command, like
a while or until loop, or a case statement - but there are often advantages to
writing the script that way.

  | I suggest including an example somewhere in the paragraph
  | since it won't be read in the context of the PR. 

On that second line (here), no, of course, the PR context if just
for this e-mail discussion.
[...]
  | Lastly, I'm wondering if it would be helpful to include a statement on
  | best-practice or a good idiom here.

Here (for both of the above suggestions) I was really hoping for ways to mak
there be less added text, rather than more, but I can see your point.

Perhaps both of those could be handled if this (even bigger) extra text was to
be added after (the corrected version of) what I sent before...

[ Aside: Note that this extra example is about as long as the (too long) text
  I sent in the previous message - both before and after the correction you
  suggested - and the original (retained though slightly modified) text about
  command substitution,  combined!
]

     For example, assuming a script were to contain the following code (which
     could be done better other ways, attempting this kind of  trickery is not
     recommended):

           if [ "$( printf "Ready? " >&2; read ans; printf "${ans}";
               { sleep 120 >/dev/null && kill $$ >/dev/null 2>&1; }& )" = go ]
           then
                   printf Working...
                   # more code
           fi

     the "Working..." output will not be printed, and code that follows will
     never be executed.  Nor will anything later in the script (unless SIGTERM
     is trapped or ignored).

     The intent is to prompt the user, wait for the user to answer, then if
     the answer was "go" do the appropriate work, but set a 2 minute time
     limit on completing that work.  If the work is not done by then, kill the
     shell doing it.

     It will usually not work as written, as while the 2 minute `sleep' has
     its standard output redirected, as does the `kill' that follows (which
     also redirects standard error, so the user would not see an error if the
     work were completed and there was no parent process left to kill); the
     sub-shell waiting for the `sleep' to finish successfully, so it can start
     the `kill', does not.  It waits, with standard output still open, for the
     2 minutes until the sleep is done, even though the kill is not going to
     need that file descriptor, and there is nothing else which could.  The
     command substitution does not complete until after the kill has executed
     and the background sub-shell finishes - at which time the shell running
     it is presumably dead.

     Rewriting the background sub-shell part of that as
           { sleep 120 && kill $$ 2>&1; } >/dev/null &
     would allow this sh to perform as expected, but that is not guaranteed,
     not all shells would behave as planned.  It is advised to avoid starting
     background processes from within a command substitution.


Does this actually help, or is all this text just making it less likely that 
the average script writer will ever read any of it?

Of course, if we want to retain this new example text, or something like it,
then help improving it would be appreciated as well.

kre



Home | Main Index | Thread Index | Old Index