Some shorthand after Ctrl-z. You usually (never?) have to type fg <jobspec>:
%2 # same as fg %2
%- # switch to "last" job (not the one you just suspended)
%vim # switch to job whose invocation started with "vim" (error if more than one)
I think it’s gotten a lot less common with the rise of screen/tmux. It’s also a lot less error prone than disown as iirc you need to first resume the job via bg otherwise you disown a stopped job. Both zsh and bash warn about it, but it’s still kind dumb.
I been slowly moving from zsh to nushell lately. Unfortunately, it doesn’t have job control yet. On the bright side, they provide an integration with pueue, which is pretty nifty.
My mind is a bit blown that people who work in the shell a lot might not (have had to find out how to) use job control. How do they navigate their processes? Or do they not, but have to quit and restart editors all the time? Nightmare.
I often have several vim sessions running in each tmux window or even pane, and switch between them with jobs and fg all the time. I’d feel very lost without it.
Another neat job control tool that isn’t mentioned here is nohup, which is like a more intentional/planned version of bg / disown.
Lots of xterms. Or Termimal windows. Oh, and if that means I ssh a bunch of times to a server, so be it. I’ll generally have one window for the editor, one to compile, and one to test/debug. Or more than one for editing multiple files.
What, like multiple actual GUI windows? Wow, OK. Completely different approach. I like to keep all terminal stuff in one terminal (well, Alacritty) window. This is a big part of what tmux is for, in my world. Navigate in and out of shells and panes and windows and sessions pretty much entirely with tmux commands in a single GUI/app window. Different flows for different folks I guess!
I suspect Unix job control was developed as a way to deal with only having a single, physical terminal [1] prior to wide spread use of GUIs. While I have used physical terminals on Unix, it was “because I can” and not “because I have to.”
[1] Or having to dial into a modem pool with a terminal emulator running on a home computer, before wide spread networking and access to the Internet.
It’s what I do in i3. I have Mod+Space bound to new terminal, I run my long-running command (or one I want to refer back to later), and then throw it to another workspace and forget about it. I find it a perfectly fast workflow, I’ve never felt hamstrung by letting my desktop environment do desktop environment things.
I think if I was on a non-tiling environment I would have a harder time.
My mind is a bit blown that people who work in the shell a lot might not (have had to find out how to) use job control.
I mean, I’m aware of it, because I used vim before it had term mode, but I never used it a ton outside of a quick ctrl+z. I don’t really want persistence, so I don’t use tmux much. I usually have a terminal window per monitor open with 6-7 tabs each depending on what’s going on. They could maybe be jobs, but I usually don’t want the output interspersed with my current terminal, plus a tab per project minimum.
My tab management is pretty bad though, and I usually just open a new tab when I’m switching between projects and use rg/fzf to get directly to what I want to edit. Which sometimes ends up with me having three tabs of the same project open eventually. At this point, I like the clean slate it gives me. I start over with only the file I want and slowly add context until I’m done with whatever I’m doing and then :qa
I work in the shell a lot and know about most of this but I just have a different workflow. I use lots of vim tabs and usually have a shell window and a vim window if I’m remote. I do use job control here and there and if I’m working on a box at console I’ll use it quite a lot, but I’m just so rarely in a single session window that there’s not too much benefit.
Right, OK! As in my other comment, that “rarely in a single session [I guess that means terminal session?] window” is what’s different from my way of doing things. “Opposite” kind of different!
No, not terminal session, I mean working on a box in a tty without a window manager or tmux loaded. Like the console of a server before you load a multi user mode or start ssh.
Basically only use job control when I’m in some image that doesn’t have ssh or tmux.
I use background and disown for various scripts or jobs but I’m not using it to multi task, unless I’m on some broken stripped down system. There are much better ways to multi task now.
Granted, your workflow is your workflow and if it works for you, it works for you.
Ctrl-s and Ctrl-q send the XOFF and XON flow control characters. The terminal sends them to the process feeding it to say “hey, you’re going too fast” and “Okay you can send”. They were useful when terminals didn’t have a scroll buffer. stty -ixon will turn it off so accidental Ctrl-s won’t stop your terminal.
I actually use job control all day. I use emacs, but don’t always like using emacsclient or the gui.
Ctrl-z to leave emacs, fg to bring it back. That’s about 90% of what I do, occasionally I bg a job. Also don’t forget Ctrl-s,Ctrl-q which stop/resume. If for no other reason than to understand why sometimes my terminal accidentally freezes!
Does anyone know how the shell makes sure children are killed? Not by having a list of children and a signal handler that kills them I presume, since in that case it wouldn’t get a chance to cleanup if it itself is killed with KILL, and I just tried killing a shell with KILL and subprocesses still were terminated.
It uses unix process groups. There’s a great intro to process groups and shells in chapter 8 section 8.2 of Computer Systems: A Programmer’s Perspective if you have access to a copy. Implementing a shell with job control is a common university assignment so there is likely to be lots of good material covering how it works online.
Biggest advantage to job control is that you can trigger it after the command started. While with tsp, tmux, nq, etc… You must think about it when you fire the initial command.
reason 2: background a GUI app so it’s not using up a terminal tab
This is great. If you don’t launch IDEA before launching it from the CLI on macos, it’ll stream the logs to the shell, so this will be useful in the future to avoid that outcome.
I would use shell job control more often if it could automatically log stdout, stderr, and exit code. (I.e. without having to set those up individually for each command.) I know task spooler and others exist, but as a sysadmin type, I can’t rely on those to be installed on all of the thousands of hosts I care for. Maybe I should write a shell script…
Some shorthand after
Ctrl-z. You usually (never?) have to typefg <jobspec>:this must be shell dependant, as in
kshI get/bin/ksh: %1: not foundBeen using UNIX job control for… 29 years now and TIL about
disown.I think it’s gotten a lot less common with the rise of screen/tmux. It’s also a lot less error prone than
disownas iirc you need to first resume the job viabgotherwise you disown a stopped job. Both zsh and bash warn about it, but it’s still kind dumb.In my pile of aliases I drag around between computers, probably my most used is this:
I been slowly moving from zsh to nushell lately. Unfortunately, it doesn’t have job control yet. On the bright side, they provide an integration with pueue, which is pretty nifty.
Oh, that is a lovely tool.
I think I know how to use the shell better than most people I know and I had no idea about any of this. Talk about discoverability.
My mind is a bit blown that people who work in the shell a lot might not (have had to find out how to) use job control. How do they navigate their processes? Or do they not, but have to quit and restart editors all the time? Nightmare.
I often have several vim sessions running in each tmux window or even pane, and switch between them with
jobsandfgall the time. I’d feel very lost without it.Another neat job control tool that isn’t mentioned here is
nohup, which is like a more intentional/planned version ofbg/disown.Lots of xterms. Or Termimal windows. Oh, and if that means I
ssha bunch of times to a server, so be it. I’ll generally have one window for the editor, one to compile, and one to test/debug. Or more than one for editing multiple files.What, like multiple actual GUI windows? Wow, OK. Completely different approach. I like to keep all terminal stuff in one terminal (well, Alacritty) window. This is a big part of what tmux is for, in my world. Navigate in and out of shells and panes and windows and sessions pretty much entirely with tmux commands in a single GUI/app window. Different flows for different folks I guess!
I suspect Unix job control was developed as a way to deal with only having a single, physical terminal [1] prior to wide spread use of GUIs. While I have used physical terminals on Unix, it was “because I can” and not “because I have to.”
[1] Or having to dial into a modem pool with a terminal emulator running on a home computer, before wide spread networking and access to the Internet.
It’s what I do in i3. I have Mod+Space bound to new terminal, I run my long-running command (or one I want to refer back to later), and then throw it to another workspace and forget about it. I find it a perfectly fast workflow, I’ve never felt hamstrung by letting my desktop environment do desktop environment things.
I think if I was on a non-tiling environment I would have a harder time.
I mean, I’m aware of it, because I used vim before it had term mode, but I never used it a ton outside of a quick ctrl+z. I don’t really want persistence, so I don’t use tmux much. I usually have a terminal window per monitor open with 6-7 tabs each depending on what’s going on. They could maybe be jobs, but I usually don’t want the output interspersed with my current terminal, plus a tab per project minimum.
My tab management is pretty bad though, and I usually just open a new tab when I’m switching between projects and use rg/fzf to get directly to what I want to edit. Which sometimes ends up with me having three tabs of the same project open eventually. At this point, I like the clean slate it gives me. I start over with only the file I want and slowly add context until I’m done with whatever I’m doing and then
:qaI work in the shell a lot and know about most of this but I just have a different workflow. I use lots of vim tabs and usually have a shell window and a vim window if I’m remote. I do use job control here and there and if I’m working on a box at console I’ll use it quite a lot, but I’m just so rarely in a single session window that there’s not too much benefit.
Right, OK! As in my other comment, that “rarely in a single session [I guess that means terminal session?] window” is what’s different from my way of doing things. “Opposite” kind of different!
No, not terminal session, I mean working on a box in a tty without a window manager or tmux loaded. Like the console of a server before you load a multi user mode or start ssh.
Basically only use job control when I’m in some image that doesn’t have ssh or tmux.
I use background and disown for various scripts or jobs but I’m not using it to multi task, unless I’m on some broken stripped down system. There are much better ways to multi task now.
Granted, your workflow is your workflow and if it works for you, it works for you.
Ctrl-sandCtrl-qsend the XOFF and XON flow control characters. The terminal sends them to the process feeding it to say “hey, you’re going too fast” and “Okay you can send”. They were useful when terminals didn’t have a scroll buffer.stty -ixonwill turn it off so accidentalCtrl-swon’t stop your terminal.I actually use job control all day. I use emacs, but don’t always like using emacsclient or the gui.
Ctrl-z to leave emacs, fg to bring it back. That’s about 90% of what I do, occasionally I bg a job. Also don’t forget Ctrl-s,Ctrl-q which stop/resume. If for no other reason than to understand why sometimes my terminal accidentally freezes!
Does anyone know how the shell makes sure children are killed? Not by having a list of children and a signal handler that kills them I presume, since in that case it wouldn’t get a chance to cleanup if it itself is killed with KILL, and I just tried killing a shell with KILL and subprocesses still were terminated.
It uses unix process groups. There’s a great intro to process groups and shells in chapter 8 section 8.2 of Computer Systems: A Programmer’s Perspective if you have access to a copy. Implementing a shell with job control is a common university assignment so there is likely to be lots of good material covering how it works online.
If you want it to continue running in the background, you can
reniceit too, which was useful back in the days ofemerge @world;)Outside of the vim case, I believe that Task Spooler is in most situations better than the shell job control or tmux/screen.
Biggest advantage to job control is that you can trigger it after the command started. While with tsp, tmux, nq, etc… You must think about it when you fire the initial command.
reptyr
I totally forgot about it ! I had issues getting it to work back in the days so so I gave up on it, but it is indeed a valuable tool.
or also:
nohup some long command > my.log &There’s also nq
Didn’t know about Task Spooler, and investigating a bit it turns out I used to live like 5 streets from the guy that created it!
This is great. If you don’t launch IDEA before launching it from the CLI on macos, it’ll stream the logs to the shell, so this will be useful in the future to avoid that outcome.
[Comment removed by author]
I would use shell job control more often if it could automatically log stdout, stderr, and exit code. (I.e. without having to set those up individually for each command.) I know task spooler and others exist, but as a sysadmin type, I can’t rely on those to be installed on all of the thousands of hosts I care for. Maybe I should write a shell script…
Sometimes I launch a bunch of jobs in the background from a loop, then
waitfor them to finish after. At least the times I forget about parallel xargs