aboutsummaryrefslogtreecommitdiff
path: root/src/blog
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-02-25 15:18:18 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2023-02-25 15:18:18 +0100
commit6174aa76ee061818a8ca6b0d952e90257ca3b5d4 (patch)
tree1cd02e5c474f2887fe62178b8720275bc189ea41 /src/blog
parentd0221b3325c5e0b206d744d1ffcae0fbcb96ec2a (diff)
downloadsebastiano.tronto.net-6174aa76ee061818a8ca6b0d952e90257ca3b5d4.tar.gz
sebastiano.tronto.net-6174aa76ee061818a8ca6b0d952e90257ca3b5d4.zip
Added blog post
Diffstat (limited to 'src/blog')
-rw-r--r--src/blog/2023-02-25-job-control/job-control.md145
-rw-r--r--src/blog/2023-02-25-job-control/jobs-diagram.pdfbin0 -> 27720 bytes
-rw-r--r--src/blog/2023-02-25-job-control/jobs-diagram.pngbin0 -> 56672 bytes
-rw-r--r--src/blog/2023-02-25-job-control/jobs-diagram.tex38
-rw-r--r--src/blog/blog.md1
-rw-r--r--src/blog/feed.xml7
6 files changed, 191 insertions, 0 deletions
diff --git a/src/blog/2023-02-25-job-control/job-control.md b/src/blog/2023-02-25-job-control/job-control.md
new file mode 100644
index 0000000..8fdb60b
--- /dev/null
+++ b/src/blog/2023-02-25-job-control/job-control.md
@@ -0,0 +1,145 @@
1# Job control: one shell is all you need
2
3If you work in a graphical desktop environment, you are most likely
4used to multi-tasking. You can listen to music while you type your
5blog posts, browse the web while your code compiles, and so on.
6
7But what if you are interacting with your machine via a command
8line? Sure, you can use a
9[terminal multiplexer](https://en.wikipedia.org/wiki/Terminal_multiplexer)
10like [tmux](https://tmux.github.io).
11But what if you forgot to run it before starting your tasks? And now
12you are updating your packages and the shell is locked?! What a nightmare!
13
14Luckily, the UNIX shell has a job control system that allows you
15to run multiple tasks at the same time. What I explain in this post
16has been tested on ksh on OpenBSD, but should work in the same way
17on Linux or any UNIX-like OS with a POSIX-compatible shell - except
18perhaps for the key combinations to suspend or kill a job.
19
20This post is not meant to be an introduction to what the shell is,
21but it is worth spending a few words to clear up some common (and
22understandable) confusion. I'll keep them really *a few*.
23
24## The terminal vs the shell, in 42 words
25
26A [terminal emulator](https://en.wikipedia.org/wiki/Terminal_emulator)
27is a program that displays text, usually coming from a
28[shell](https://en.wikipedia.org/wiki/Shell_(computing)).
29The shell reads text, normally entered by the user, and
30interprets it. If this text instructs it to run another program, it
31spawns a new [process](https://en.wikipedia.org/wiki/Process_(computing))
32for it.
33
34## Foreground and background jobs
35
36A *job* is an entity that runs in the shell when you issue a command.
37A job can consist of more than one process, for example if you
38run multiple commands in a
39[pipeline](https://en.wikipedia.org/wiki/Pipeline_(Unix)).
40When you try to close a shell, it usually warns you if you have
41running jobs *attached* to it, since it will *kill* them before
42it closes - that might depend on the shell's configuration and
43launch options, though.
44
45When you run a program by typing its name of in a shell, say a text
46editor like vi, this program "takes over" the shell. You can't run
47any other command until this program terminates - or so it seems.
48This happens also with most GUI programs, like firefox or gedit:
49if you run them from a shell you will see some log messages, but
50the shell is otherwise useless. This is the intendend behavior, and
51this job is said to be running in the *foreground*. At any time
52there can be at most one foreground job in a given shell.
53
54If you have read my previous
55[blog entry on the shell](../2022-09-13-sh-1), you should know that
56you can launch a command in the *background* by adding an `&`
57at the end of the line. Background jobs do not "block" the shell,
58but they still use it to print their output.
59
60So jobs can be running in the foreground or in the background of a
61shell. There is also a third possible state for a shell's job: it
62can be *suspended*. On most UNIX shells you can suspend a foreground
63job by pressing `Ctrl`+`Z`. Try it: if you open `vi`, or any other
64terminal-based program, and press `Ctrl`+`Z`, you are sent back to
65a command prompt. This is even more fun with a graphical application:
66its whole window becomes unresponsive and you can't even close it!
67(Ok, I admit my definition of "fun" might be... unusual)
68
69## Full job control
70
71So far we have seen how to run commands (jobs) in the foreground
72(default behavior) or in the background (using `&`), and how to
73suspend the job in the foreground (with Ctrl+Z). But we can do more.
74
75To get an overview of the jobs attached to the current shell, you
76can use the `jobs` command. If you run it while you have some
77backgrounded or suspended jobs, you'll something like this:
78
79```
80[3] + Suspended vi
81[2] - Suspended cat
82[1] Running ./git/nissy/nissy
83```
84
85The number in brackets is the job's *ID*. It is followed by the
86job's status (Done, Running, Suspended or Stopped) and the command
87that started the job. If you use the `-l` option you'll get the
88job's *process ID*, or PID, too.
89
90You can use this information to change a job's status with the
91`fg` and `bg` builtins. For example, typing
92
93```
94$ fg %job_id
95```
96
97makes a currently backgrounded or suspended job run in the foreground.
98Similarly
99
100```
101$ bg %job_id
102```
103
104makes a currently suspended job run in the background. As far as I
105know, there is no way to tell the job running in the foregroung to
106pass to the background - you have to suspend it first, and then use
107`bg`.
108
109You can replace `%job_id` with the job's PID (without percent
110symbol) or with `%string`, where `string` is the beginning of the
111job's name. If you call `fg` or `bg` without any argument, the job
112marked by a `+` in the jobs list is selected. You can select the
113job marked by a `-` with `%-`
114
115All of this is summed up in the following diagram:
116
117![Diagram showing how to change the status of a job](jobs-diagram.png)
118
119*Picture generated with [tikz](https://github.com/pgf-tikz/pgf)
120([code, 1.2Kb](jobs-diagram.tex), [pdf, 27.3Kb](jobs-diagram.pdf)).
121Do you know a better (simpler) tool or language to generate svg
122graphics and diagrams programmatically? Let me know!*
123
124You may have noticed that [kill(1)](http://man.openbsd.org/kill)
125makes an appearance. I have not talked about it yet, and I won't
126go over it in detail in this post, but to put it briefly you can
127use `kill` to send certain [signals](http://man.openbsd.org/signal)
128to a process or job - such as `SIGSTOP` to suspend and `SIGTERM` to
129terminate. This is what pressing a Ctrl+Z or Ctrl+C actually does
130under the hood.
131
132## Conclusion
133
134With just a few simple bultins and keyboard sortcuts, the UNIX shell
135gives some good flexibility in managing running jobs. If, like me,
136you run most of your shells in a graphical terminal emulator or in
137a tmux session, you can already get all the flexibility you want
138by opening a new terminal window. But the ability to suspend jobs
139and resume them later might be something new. Moreover, you might
140find yourself in a situation where spawning a new window is not an
141option - for example if you are connected to a remote machine via
142ssh and you forgot to run tmux when you logged in.
143
144I hope you found this post interesting. I certainly enjoyed
145writing it, and I learnt a couple of new tricks in the process.
diff --git a/src/blog/2023-02-25-job-control/jobs-diagram.pdf b/src/blog/2023-02-25-job-control/jobs-diagram.pdf
new file mode 100644
index 0000000..a2e497b
--- /dev/null
+++ b/src/blog/2023-02-25-job-control/jobs-diagram.pdf
Binary files differ
diff --git a/src/blog/2023-02-25-job-control/jobs-diagram.png b/src/blog/2023-02-25-job-control/jobs-diagram.png
new file mode 100644
index 0000000..484e7b9
--- /dev/null
+++ b/src/blog/2023-02-25-job-control/jobs-diagram.png
Binary files differ
diff --git a/src/blog/2023-02-25-job-control/jobs-diagram.tex b/src/blog/2023-02-25-job-control/jobs-diagram.tex
new file mode 100644
index 0000000..0a919db
--- /dev/null
+++ b/src/blog/2023-02-25-job-control/jobs-diagram.tex
@@ -0,0 +1,38 @@
1\documentclass[crop, tikz]{standalone}
2\usepackage{tikz}
3
4\begin{document}
5\begin{tikzpicture}
6\usetikzlibrary{arrows.meta}
7
8% Just a workaround to leave some space around the diagram
9\filldraw[color=white,fill=white] (-8,-9) rectangle (8,1);
10
11% Boxes
12\newcommand{\tbox}[3]{
13 \node[draw, rounded corners, text centered, text width=3cm]
14 (#1) at (#2) {\bf #3}
15 ;
16}
17\tbox {top} {0,0} {Job not running}
18\tbox {left} {-6,-4} {Job running in the background}
19\tbox {right} {6,-4} {Job running in the foreground}
20\tbox {bottom} {0,-8} {Job suspended}
21
22% Arrows
23\newcommand{\arr}[4]{
24 \draw[-{Latex[length=3mm]}, ultra thick]
25 (#1) edge[#4] node[fill=white] {\texttt{#3}} (#2)
26 ;
27}
28\arr {top} {left} {command \&} {bend right}
29\arr {left} {top} {kill \%job} {bend right}
30\arr {left} {bottom} {kill -STOP \%job} {bend right}
31\arr {bottom} {left} {bg \%job} {bend right}
32\arr {bottom} {right} {fg \%job} {bend left}
33\arr {right} {bottom} {Ctrl+Z} {bend left}
34\arr {right} {top} {Ctrl+C} {bend left}
35\arr {top} {right} {command} {bend left}
36\arr {left} {right} {fg \%job} {}
37\end{tikzpicture}
38\end{document}
diff --git a/src/blog/blog.md b/src/blog/blog.md
index d6ce61d..8bd57ea 100644
--- a/src/blog/blog.md
+++ b/src/blog/blog.md
@@ -5,6 +5,7 @@
5 5
6## 2023 6## 2023
7 7
8* 2023-02-25 [Job control: one shell is all you need](2023-02-25-job-control)
8* 2023-01-28 [The year of the Windows desktop](2023-01-28-windows-desktop) 9* 2023-01-28 [The year of the Windows desktop](2023-01-28-windows-desktop)
9* 2023-01-11 [Aaron Swartz](2023-01-11-aaron-swartz) 10* 2023-01-11 [Aaron Swartz](2023-01-11-aaron-swartz)
10 11
diff --git a/src/blog/feed.xml b/src/blog/feed.xml
index 9bbb571..88f547b 100644
--- a/src/blog/feed.xml
+++ b/src/blog/feed.xml
@@ -9,6 +9,13 @@ Thoughts about software, computers and whatever I feel like sharing
9</description> 9</description>
10 10
11<item> 11<item>
12<title>Job control: one shell is all you need</title>
13<link>https://sebastiano.tronto.net/blog/2023-02-25-job-control</link>
14<description>Job control: one shell is all you need</description>
15<pubDate>2023-02-25</pubDate>
16</item>
17
18<item>
12<title>The year of the Windows desktop</title> 19<title>The year of the Windows desktop</title>
13<link>https://sebastiano.tronto.net/blog/2023-01-28-windows-desktop</link> 20<link>https://sebastiano.tronto.net/blog/2023-01-28-windows-desktop</link>
14<description>The year of the Windows desktop</description> 21<description>The year of the Windows desktop</description>

Generated with cgit - Back to sebastiano.tronto.net