-
Notifications
You must be signed in to change notification settings - Fork 2k
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 statement cannot work with functions? #238
Comments
On Linux, executing "vi &" doesn't take vi to background, and at exit I get following message : Job 1, “vi &” has ended Is anyone else able to reproduce it ? |
fish probably doesn't spawn a subshell for functions executed as background jobs. If it did, those jobs probably could not do things like update global variables. |
Seems to work correctly here using fish packaged in debian: Could be a regression? |
I had written a function named "vi" (alias like) to invoke vi editor, so I was not able to invoke vi in background. This should be fixed, we need to add support for executing functions in background. |
This bit me in a rather confusing way just now. Several weeks ago I defined an alias: I understand what you're saying about subshells for functions being overkill, but I think that, as with the !! syntax, if there is a way to achieve this functionality without changing things, it'll meet the expectations of more people migrating from bash/zsh, because you can background just about everything in a bash. Thanks again for all your work on this awesome shell! |
This is a known problem, see also issue #563. Unlike most other shells fish is a multithreaded program, so it can not |
(Documentation for fish-shell#238, fish-shell#563)
Ah. Well that would also explain #1040 then, I think. |
Hm, what if calls to builtins, like |
@maxnordlund The biggest obstacle is that fish uses the C stack for builtins, functions, and command substitutions. Therefore executing two of these concurrently means multiple threads, multiple processes, or something like coroutines. I have a branch that tries to support multithreaded execution, but it's very complex so I'm not optimistic that it will work. |
I was leaning towards multiple threads, and come to think of maybe it would be easier if script execution was always running in the background. Every time it needed a builtin it synchronized/sent a message to the main thread to do the work. Sort of like most GUI frameworks keep one thread responsible for rendering, and you always have to ask it if you need an update. |
Fish shell already uses libevent, right? Couldn't we keep it single threaded, but switch builtin and function execution to an asynchronous or coroutine model? That solves the global state atomicity issue- only one piece of code is ever running at a time, so changes to variables, working directory, etc all happen atomically. Once all pipelines are converted to true unix pipes, rather than being fully buffered between functions (see #936), the pipe's file descriptors can be selected over in the libevent event loop, allowing for single-threaded concurrency in the same vein as node.js or python's asyncio. We should probably assume that users who are backgrounding fish functions are aware and accepting of the possibility of global state mutation, rather than attempting to simulate multiple working directories (for instance, with function contrived
sleep 5
set -g MY_VAR hello
cd $argv[1]
end
contrived /another/directory The user clearly wants the current shell to switch to |
No, fish does not use libevent. Making the internals thread safe is part of it. There's also the issue of replicating process state. For example, we need to have multiple variable stacks, since two separately executing functions need independent local variables. We need separate values of I did some work on this in the multithreaded_execution branch, but I think as it stands it adds too much complexity to merge, and if we want to go down this path, it will involve a lot of rewriting. |
Are there any plans to add multithreading support to functions in the near future? |
No. With 530 open issues as I type this patches are welcomed. |
Powershell just released proper backgrounding, hopefully fish gets it soon! :) function background --description "Run a fish command in the background using a bash subshell"
bash -c "fish -c '""$argv""' &"
end
background "sleep 5; echo hi" |
...why are you using a bash shell? Why not just call `fish` directly?
…On May 20, 2017 4:34 PM, "Nick Sweeting" ***@***.***> wrote:
Powershell just released proper backgrounding
<PowerShell/PowerShell#716 (comment)>,
hopefully fish gets it soon! :)
Until then, this hack is still working well for me (though backgrounded
tasks don't have access to exported vars from the current shell):
function background --description "Run a fish command in the background using a bash subshell"
bash -c "fish -c '""$argv""' &"end
background "sleep 5; echo hi"
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#238 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABvSrfvWpWA4Rm_J9syksuGFWOiim4Mkks5r705EgaJpZM4AEwdv>
.
|
@Lucretiel notice the Edit: maybe I misunderstood, did you mean call |
I have no idea where you got that idea. What exactly is wrong with simply using fish to do this? This is commonly known as the double-fork trick and it works fine with fish. |
@krader1961, sorry I mistakenly thought that because fish had issues backgrounding functions, that I wouldn't be able to trust it to background other commands consistently as well. |
I think it is acceptable that functions cannot be put in the background, but it should be better communicated to the user. Now it just runs in the foreground anyway, even though the user requested the background: it is blocking the shell and in the end the user sees: I think in case of a request What do you think about this? Fish stands for a friendly shell: it should tell the user what it does in my humble opinion. |
You can work around the "has ended" message by putting the job start in a block: |
@sabinem I think it's also very important to birng the user attention to abbreviation. This is a feature not available in other shells most new users(and this is what happened to me) just copy their alias.sh to alias.fish source it and assume everything is gonna be okay then they run at issues such as #238 and assume their workflow is gonna be totally disrupted in fish. |
If it saves anyone 10 minuntes working out the correct way to quote, I believe this works (or will happily be corrected) as a workaround: function bgFunc
fish -c (string join ' ' (string escape $argv)) &
end |
A slight improvement on @stellarpower's wonderful function bgFunc
fish -c (string join -- ' ' (string escape -- $argv)) &
end (I happen to have arguments starting with |
This does not currently work, as fish does not yet allow functions to be sent in the background directly: https://fishshell.com/docs/current/language.html#job-control fish-shell/fish-shell#238
Would this be any easier to implement after the rust rewrite? |
Yes, and it's one of the driving factors behind the port. (Please do not ask when it is planned or when it will be ready; we can give no answers that you can action.) |
Does the "... &" statement only work with simple commands and not functions? For example, if I have defined
and execute
the output is
with the observed performance (delay) indicating that each successive "q" command is not executed until the previous command is completed. I use in POSIX sh "(sleep [some delay] && [command]) &" quite commonly in startup scripts e.g. for window managers to allow for the initialization requirements of certain apps.
If there is a correct "fish" way of spawning multiple background processes, my second question is: is there a way to spawn a block of commands in background similar to POSIX "(command1 && command2 && command3...) &". I tried "begin; ...statements...; end &" but fish does not like that!
The text was updated successfully, but these errors were encountered: