-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Background jobs #11696
base: main
Are you sure you want to change the base?
Background jobs #11696
Conversation
This PR makes use of Currently, there is no way to redirect stdout and stderr for a background command, but I plan to add support for redirection ( Other things to work out:
|
Excited for this 💥 !!! |
Good job! I want to have something like this for a long time! Regarding to your questions:
I think it's good to report additional information in a record.
Yup, I think once we press enter, messages can be printed, it just shows something is finished, and user can get more information from job list.
Refer to showing completed jobs status, I think we don't need to remove it. Personally I'd prefer an explicit prune flag, or something like
We can iterate on it. Just curious, does
I'd say yes and no. Generally I'm agree with you, not really sure is there a way to auto "disown" jobs when it starts? (like
Yup :) |
@WindSoilder thanks for the feedback!
Makes sense, will work on that!
Sounds good, will be added :)
I was thinking along those lines was well. I think the
Yep, exactly. I was thinking it would send
Yeah, in the future there should be a way to start a job disowned. I'm thinking that a My original comment was slightly inaccurate for unix. If the shell exits, so nothing is reading stdout/stderr for a background job, then the job will receive a |
Finally had a chance to look at this. It seems much more tied to external command management than I was thinking, which kind of makes my idea of using closures probably not work so well. I think being able to find the PID of jobs and cancel them is probably more important than supporting background jobs written in nu, so I'm in support of this, unless it's reasonable to try to do both. |
The original plan was to later generalize this to closures instead of only allowing a single external command. Since the external printer with reedline seems to be a little tricky to do, I'm leaning towards having background jobs always detached from the terminal, and then to have some way to view the job output log so far. With this approach, I think it shouldn't be too hard to implement closures from the start (and perhaps only closures). |
Very cool 😎 Regarding |
The currently discussed implementation of
From a scripting viewpoint, it would be helpful if the output of the job were also stored for later retrieval. Additionally, I have some suggestions that may extend beyond the current scope:
The
Implementing
The Syntactically, Additional thoughts: Unless I'm missing something, it should be relatively straightforward to manually implement The purpose of the
|
Wouldn't this approach in NuShell create the same bottleneck as in |
Description
This PR adds support for simple, single command background jobs. Background jobs are started using the
job start
command. This takes an external command and its arguments (just likerun-external
) and runs the command in the background. The current list of jobs can be shown usingjob list
. The output from this is TBD, but it currently shows the job ids, pids, command, and status (running or completed). For now, completed jobs are removed from the list after callingjob list
.Technical Details
In non-interactive mode, jobs inherit stdin, stdout, and stderr and are can write to them without synchronization.
But, when the shell is in interactive mode, background jobs are started disconnected from the terminal: their stdin, stdout, and stderr are piped rather than inherited. This is to prevent background jobs from directly printing to the terminal when editing the prompt in the repl. This is a problem, since reedline puts the terminal in raw mode while editing, which means printed new lines will not return the cursor to the start of the line. So, you can get output like this:
With the reedline external printer, the output should much nicer like this:
Additionally, the external printer makes sure that there are no intermingled or partial lines. If multiple background jobs print at the same time, each line is added atomically (this has a slight performance penalty, but it should hopefully be reasonable considering that stdout is locked behind a mutex in the Rust standard library).
The downside to this is that background jobs cannot be directly attached to the terminal. Some programs behave differently depending on whether they detect that stdin/stdout is a terminal. For example, nushell itself will fail:
The
--inherit
/ interactive flag can be used to force background jobs to use the terminal with weird effects:On unix, this child nushell will stop itself since it is not in control of the terminal. There is currently no way to move background jobs to the foreground, so this job will be forever stopped unless it is killed or the parent nushell exits. Also, output from any jobs launched with the
-i
flag will create messed up new lines as described above.User-Facing Changes
Adds the
job start
andjob list
commands.Tests + Formatting
TODO
After Submitting
TODO