Default `fg` when only one job is backgrounded
Describe the problem:
When only one job is in the background, it seems excessive to require the PID/FID to reactivate it - the user can only really mean one thing by typing fg.
Possible ways to implement:
Automatically foreground process on fg when there is only a single job.
Documentation: Please rate your success with referring to the docs @ https://murex.rocks
- [ ] I haven't read the docs / the solution should be more discoverable
- [ ] I have read the docs but the content wasn't clear
- [x] I have read the docs but this query was missing
- [ ] I have read the docs and this query was answered but I'm still having problems
Coincidentally, I've been thinking about adding a few enhancements to fg too. Such as supporting % prefixes like Bash (et al) do.
So it wouldn't take any extra effort to make fg default to %1 if no parameters are supplied.
Nice!
Perhaps a touch bikesheddy but IMO Bash-esque % prefixes can induce extra cognitive load when you're juggling more than 1-2 processes. If you're already going that route, would you consider perhaps %partialprocessname, ie. fg %py could foreground the process called by python my_web_server.py? (Of course, preferring errors to ambiguity, so if there are two bg python processes we don't act.)
I could easily add support for partial process names without the % prefix. Basically the logic would go:
- is it an integer? If so, it's a FID
- is it a
%prefixed integer? If so, follow Bash's format (for people with Bash muscle memory) - otherwise, assume its a partial process name
I've finally gotten round to adding the following parameter support for bg and fg:
- zero length string,
^$: latest job - numeric,
^[0-9]+$: corresponding function id - percent sigil,
^%[0-9]+$: corresponding job id - any other character sequence: partial command / parameters lookup
jobs now presents the job ID:
» jobs
JobID FunctionID State Background Process Parameters
%1 369 Executing true try { update-aws-hosts }
%2 370 Executing true update-aws-hosts
%3 373 Executing true foreach-aws-profile { ec2-describe-instances -> set hosts GLOBAL.AWS_HOSTS <~ $hosts }
%4 376 Executing true foreach ENV.AWS_PROFILE$1
%5 446 Executing true set hosts
%6 445 Executing true ec2-describe-instances
%7 456 Executing true foreach --jmapres{ $res.Instances.0.NetworkInterfaces.0.PrivateIpAddress }{ printf <!null> %(${@res.Instances.0.tags[{ $.Key=="Name" }] -> [[.0.Value]] || $res.Instances.0.InstanceId} on $AWS_PROFILE (${$res.Instances.0.State.Name})) }
%8 454 Executing true aws ec2describe-instances
%9 455 Executing true [ Reservations]
%10 459 Executing true exec aws--outputjson--no-paginate--no-cli-pager--colorauto@PARAMS
Naturally, none of this is documented....yet. But it is available in develop.
Seems to be working rather smoothly so far, great stuff. I'm not sure if I'm misunderstanding or misusing the process lookup, though - bg { sleep 1000 }; fg sl says no matching process is found, for example.
Okay, so looking closer at the jobs, the process name is always set to exec. From what you said about command/params, it should use the full argc+argv for the process lookup instead, right?
Seems to be working rather smoothly so far, great stuff. I'm not sure if I'm misunderstanding or misusing the process lookup, though -
bg { sleep 1000 }; fg slsays no matching process is found, for example.
That might be because fg is running before bg has had a chance to invoke sleep.
There's certainly some polish I can put around bg to make it behave more intuitively. But I'm yet to stumble upon ways of achieving this which doesn't violate other expectations. So for now, you have to consider anything inside bg {} to be completely asyconous to the point that even the first command (eg sleep in your example) might still start after the next command that follows bg (eg fg in your example)
Okay, so looking closer at the jobs, the process name is always set to exec. From what you said about command/params, it should use the full argc+argv for the process lookup instead, right?
External processes will always start with exec. It was an old decision from when the shell was young as a way of namespacing builtins from external executables. In practice it doesn't really add much value. I might look to remove it from v7.0 but in terms of bg and fg usage, it shouldn't make any difference because (as you said) the look up is against both the name and parameters. Do let me know if you're finding this not to be the case
Yes, the semicolon was shorthand, sorry - the process is definitely alive but only "exec" or some part thereof can be used as a string to foreground it. No other name or parameter seems to work
Ahhh I can see what's happening:
dev » bg {sleep 20}
dev » jobs
JobID FunctionID State Background Process Parameters
%1 898 Executing true exec 20
Either process should be sleep or parameters should be sleep 20.
What I've done is tried to tidy the parameters (essentially hide the fact that every process is an exec) but done a half-arsed job of it.
Sorry about that. I can get that sorted easily enough though
Turns out you've uncovered a much deeper bug then I first thought.
There's a quick way of fixing this, but I'm taking my time on this because I think there is some small performance gains to be made here (we are admittedly talking about micro-optimisations, but it's micro-optimisations that could also lead to cleaner code, so a win-win situation)
I pushed a fix to develop at the weekend. Let me know if you run into any further bugs or issues