[Toybox] Would someone please explain what bash is doing here?

Chet Ramey chet.ramey at case.edu
Thu May 28 14:08:36 PDT 2020


On 5/27/20 6:17 PM, Rob Landley wrote:

>> But what are you going to do with a shell script when you suspend a
>> pipeline in it? Keep on going with reading commands in the script? That's
>> rarely going to be what the user wants. Most people expect the shell
>> running the script to get suspended when you hit it with SIGTSTP.
> 
> To be honest I'm leaning towards doing that and seeing who complains.

That is, unfortunately, not conformant. If you set -m in a script, and
run an external command, that command gets put in its own process group,
and the terminal pgid is set to that process group, and that process
group gets the SIGTSTP. If you want, you can notice the stopped job and
resend SIGTSTP to yourself, but nobody except ksh93 does that. It's just
a bad idea for users to try it.

>>> The man page has more "written by somebody who already knows it" stuff:
>>>
>>>        referred to as %n.  A job may also be referred to using a prefix of the
>>>        name used to start it, or using a substring that appears in its command
>>>        line.  For example, %ce refers to  a  stopped  ce  job.   If  a  prefix
>>>        matches  more  than one job, bash reports an error.  Using %?ce, on the
>>>        other hand, refers to any job containing the string ce in  its  command
>>>        line.   If  the  substring  matches  more than one job, bash reports an
>>>
>>> That "%?ce" is a specific example, not an explanation of what's happening here.
>>
>> It's a specific example of a program named `ce' being suspended. It could
>> be any program. That's why the man page has `ce' in bold.
> 
> It's a program name _starting_ with ce. I got that part. (Doesn't seem to be a
> way to do an exact match, I'd guess curly braces but probably not?)
> 
> But no, you don't need the ? for it to be a prefix:

Correct, that's what the man page says.


> You need the ? to match an argument instead of a command name. 

And that is, too.

>>> Is it because "?" is a wildcard, or because %? is a special prefix? 
>>
>> It's because `%' introduces the job spec, and `?' is the notation to refer
>> to the substring of the job name, so the latter.
> 
> Special prefix, yay.

If you support job control IDs, you're already supporting `%' as a special
prefix. What's the difference?

> 
>>> That
>>> question mark isn't going to act as a wildcard and match a filesystem character
>>> during normal wildcard processing, right?
>>
>> It could. These are invariably used as arguments to builtins, and undergo
>> all the usual word expansions.
> 
> So it's %\?ce

Depending on your level of paranoia.

> 
>>> If there's a %xce in the current
>>> directory, it won't resolve to that? 
>>
>> It could. Such filenames are extremely rare. I've never actually had a bug
>> report complaining about this.
> 
> I BREAK EVERYTHING. Trust me, if I started using this feature, I would hit this.

You often name files beginning with percents?

> 
>>> The % is parsed _before_ wildcards and
>>> suppresses normal wildcard expansion? 
>>
>> No. fg/bg/jobs/kill/wait/disown are not special in that regard.
> 
> Despite being shell builtins. Ok.

It's *because* they are shell builtins. They are not reserved words.
Builtins and their arguments undergo the same word expansions as non-
builtin commands.

> 
>>> If a $variable expands to %?ce does it
>>> still count? 
>>
>> Yes, when it's used as an argument to a shell builtin.
> 
> Alright, it's not parsed by the shell it's just consumed by commands so I should
> document %\? as the prefix.

Just wait until you get users saying "I typed '%\\?sle' and nothing
happened."



>>> Asynchronous! Not really designed to be scripted!
>>
>> Asynchronous jobs are easy. Once you have something in the background, and
>> you know its job number or how to refer to it using %name, you can run bg
>> and fg to your heart's content, use `kill' to kill it, and use `wait' to
>> clean up.
> 
> A test suite that assumes all the tests _succeed_ is easy to write.

If you mean "succeed or fail in predictable ways when given incorrect
input," sure.

If you're worried about leaving stray background jobs around, end your
test script with `wait'. But you can always save a background job's pid
by saving $!, so you can always have a handle to the background jobs you
create.

Bash-5.1 will change the way it does $SECONDS to use gettimeofday(), btw.
We already talked about the readonly stuff.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet at case.edu    http://tiswww.cwru.edu/~chet/


More information about the Toybox mailing list