3 ms·
The one thing I miss most in fish is subshells, because I love writing things like ( (cd $dir && ./run_prog && cd PKG && ./do_stuff) & ), to run a series of thi
by CJefferson 8y ago
The one thing I miss most in fish is subshells, because I love writing things like ( (cd $dir && ./run_prog && cd PKG && ./do_stuff) & ), to run a series of things in the background. Is there any way to do something similar in fish?
- faho 8y agoWhat this does is two things: - It keeps the state separate from the main shell, including $PWD (so the `cd` doesn't affect the main execution "thread") - It executes some script in the background Fish's backgrounding is currently limited to single external commands (not even functions). That's https://github.com/fish-shell/fish-shell/issues/238 https://github.com/fish-shell/fish-shell/issues/238. It also doesn't have the capability to keep $PWD separate, though other variables can of course be declared locally. That's https://github.com/fish-shell/fish-shell/issues/1439 https://github.com/fish-shell/fish-shell/issues/1439. The workaround is, if you actually need this, to run it inside `fish -c`. Which is essentially what this syntax is doing in the background anyway (it needs to fork off because `chdir` applies to the entire process). (Disclosure: I'm a fish developer)
- SomeHacker44 8y agoForking off a subshell is very different, I would think, than forking and execing a new shell, both from a resource standpoint and an open file standpoint.
- faho 8y agoNot really from a usage perspective though, and resources often don't matter. If you're doing something like this in the background, then that usually means it takes a "long" time (or you'd just wait for it). So the overhead of starting an additional shell simply isn't important. Not that it's always irrelevant, but that's why the issues are still open.
- SomeHacker44 8y agoAgreed, resources often don't matter. But I do often do something like: ( cd somewhere ; do_something ) just so I can avoid having to do pushd somewhere ; do_something ; popd (or the equivalent).
- barrkel 8y agoDifference being that the fork is copy on write, so it can be quite a bit faster and need no initialization. Not to mention not needing to quote quotes and escape escapes.
- zcoyle 8y agoI didn't know about subshells. I'm going to be using that all the time now, thanks!
- barrkel 8y agoI also do that, often with loops. for ((i=0;i<4;++i)); do (./ad-hoc-operation >out-$i.log 2>&1 ) & done Can be anything from image processing, video transcoding, file decompression, file system analysis - anything I think may complete faster with some concurrency.
- CJefferson 8y agoThat's a nicer notation than me! I thought you needed a ; before the 'done', and & ; won't parse.
- brendyn 8y agoSomething like this should do the same thing, I think?: seq 0 3 | parallel "./ad-hoc-operation > out-{}.log" https://www.gnu.org/software/parallel/ https://www.gnu.org/software/parallel/
- CJefferson 8y agoWith longer expressions, I find the escaping gets tricky. Also gnu parallel has stupid licence problems and the author has told me I can't use it without paying him.
- barrkel 8y agoMight do. OTOH I often have a shell pipeline as the body of the loop, rely on glob expansion, etc. For ad-hoc parallelism of a simple command over lots of data, I tend to use xargs -n -P - since I use xargs for other things, I stick with it. Also, bash and xargs are available everywhere, on production servers as well as dev laptops. Anything that requires installing something has a big hurdle to overcome - this counts for fish too.