<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SysAdmin on dwmkerr.com</title><link>https://dwmkerr.com/tags/sysadmin/</link><description>Recent content in SysAdmin on dwmkerr.com</description><generator>Hugo -- gohugo.io</generator><language>en-uk</language><managingEditor>Dave Kerr</managingEditor><copyright>Copright &amp;copy; Dave Kerr</copyright><lastBuildDate>Tue, 25 Jun 2019 07:25:23 +0000</lastBuildDate><atom:link href="https://dwmkerr.com/tags/sysadmin/index.xml" rel="self" type="application/rss+xml"/><item><title>Effective Shell Part 7: The Subtleties of Shell Commands</title><link>https://dwmkerr.com/effective-shell-7-shell-commands/</link><pubDate>Tue, 25 Jun 2019 07:25:23 +0000</pubDate><guid>https://dwmkerr.com/effective-shell-7-shell-commands/</guid><description>&lt;p&gt;In this chapter, we&amp;rsquo;ll take a look at the various different types of shell commands that exist and how this can affect your work.&lt;/p&gt;
&lt;p&gt;By the end of this chapter, you might even be able to make sense of the horrifying and perfectly syntactically valid code below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;which &lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;where &lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;what &lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;whence &lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;whereis who&lt;span style="color:#66d9ef"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.dwmkerr.com/effective-shell-part-1-navigating-the-command-line/"&gt;Part 1: Navigating the Command Line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dwmkerr.com/effective-shell-part-2-become-a-clipboard-gymnast/"&gt;Part 2: Become a Clipboard Gymnast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dwmkerr.com/effective-shell-part-3-getting-hepl/"&gt;Part 3: Getting Help&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dwmkerr.com/effective-shell-4-moving-around/"&gt;Part 4: Moving Around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dwmkerr.com/effective-shell-part-5-understanding-the-shell/"&gt;Part 5: Interlude - Understanding the Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dwmkerr.com/effective-shell-6-job-control/"&gt;Part 6: Everything You Don&amp;rsquo;t Need to Know About Job Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dwmkerr.com/effective-shell-7-shell-commands/"&gt;Part 7: The Subtleties of Shell Commands&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-are-commands"&gt;What Are Commands?&lt;/h2&gt;
&lt;p&gt;This is &lt;em&gt;really&lt;/em&gt; important to understand! A &lt;em&gt;command&lt;/em&gt; in a shell is something you execute. It might take parameters. Generally it&amp;rsquo;ll have a form like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;command param1 param2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;ve already seen many commands during this series:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls &lt;span style="color:#75715e"&gt;# Show the contents of the current directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd ~ &lt;span style="color:#75715e"&gt;# Move to the user&amp;#39;s home&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat file.txt &lt;span style="color:#75715e"&gt;# Output the contents of &amp;#39;file.txt&amp;#39; to stdout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But to be an effective shell user, you must understand that not all commands are created equal. The differences between the types of commands will affect how you use them.&lt;/p&gt;
&lt;p&gt;There are four types of commands in most shells:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Executables&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Built-Ins&amp;rdquo; (which we&amp;rsquo;ll just call &lt;em&gt;builtins&lt;/em&gt; from now on)&lt;/li&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Aliases&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&amp;rsquo;s quickly dig in and see a bit more.&lt;/p&gt;
&lt;h2 id="executables---programs"&gt;Executables - Programs&lt;/h2&gt;
&lt;p&gt;Executables are just files with the &amp;rsquo;executable&amp;rsquo; bit set&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;. If I execute the &lt;code&gt;cat&lt;/code&gt; command, the shell will search for an executable named &lt;code&gt;cat&lt;/code&gt; in my &lt;code&gt;$PATH&lt;/code&gt;. If it finds it, it will run the program.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ cat file.txt
This is a simple text file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What is &lt;code&gt;$PATH&lt;/code&gt;? &lt;code&gt;$PATH&lt;/code&gt; is the standard environment variable used to define &lt;em&gt;where&lt;/em&gt; the shell should search for programs. If we temporarily &lt;em&gt;empty&lt;/em&gt; this variable, the shell won&amp;rsquo;t find the command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt; cat file.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bash: cat: No such file or directory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Normally your &lt;code&gt;$PATH&lt;/code&gt; variable will include the standard locations for Linux programs - folders such as &lt;code&gt;/bin&lt;/code&gt;, &lt;code&gt;/sbin&lt;/code&gt;, &lt;code&gt;/usr/bin&lt;/code&gt; and so on&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;If you were to print the variable, you&amp;rsquo;d see a bunch of paths (they are separated by colons; I&amp;rsquo;ve put them on separate lines for readability):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The shell will start with the &lt;em&gt;earlier&lt;/em&gt; locations and move to the later ones. This allows &lt;em&gt;local&lt;/em&gt; flavours of tools to be installed for users, which will take precedence over &lt;em&gt;general&lt;/em&gt; versions of tools.&lt;/p&gt;
&lt;p&gt;There will likely be other locations too - you might see Java folders, package manager folders and so on.&lt;/p&gt;
&lt;h2 id="executables---scripts"&gt;Executables - Scripts&lt;/h2&gt;
&lt;p&gt;Imagine we create a text file called &lt;code&gt;dog&lt;/code&gt; in the local folder:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;🐶 woof 🐶&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If we make the file &lt;em&gt;executable&lt;/em&gt;, by running &lt;code&gt;chmod +x dog&lt;/code&gt;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;, then we can run this just like any other program - as long as we tell the shell to look for programs in the current directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;.&amp;#34;&lt;/span&gt; dog
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;🐶 woof 🐶
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;More common would be to run the program by giving a path:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ./dog
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;🐶 woof 🐶
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or just move it to a standard location that the shell already checks for programs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ mv dog /usr/local/bin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ dog
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;🐶 woof 🐶
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The point is that executables don&amp;rsquo;t &lt;em&gt;have&lt;/em&gt; to be compiled program code. If a file starts with &lt;code&gt;#!&lt;/code&gt; (the &amp;lsquo;shebang&amp;rsquo;), then the system will try to run the contents of the file with the program specified in the shebang.&lt;/p&gt;
&lt;p&gt;We will look at shebangs in greater detail in a later chapter.&lt;/p&gt;
&lt;h2 id="builtins"&gt;Builtins&lt;/h2&gt;
&lt;p&gt;OK, so we&amp;rsquo;ve seen executables. What about a command like this?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local V&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt; echo $V
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You will not find the &lt;code&gt;local&lt;/code&gt; executable anywhere on your system. It is a &lt;em&gt;builtin&lt;/em&gt; - a special command built directly into the shell program.&lt;/p&gt;
&lt;p&gt;Builtins are often highly specific to your shell. They might be used for programming (&lt;code&gt;local&lt;/code&gt; for example is used to declare a locally scoped variable), or they might be for very shell-specific features.&lt;/p&gt;
&lt;p&gt;This is where we need to take note. As soon as you are running a builtin, you are potentially using a feature that is specific to &lt;em&gt;your&lt;/em&gt; shell, rather than a program that is shared across the system and can be run by &lt;em&gt;any&lt;/em&gt; shell.&lt;/p&gt;
&lt;p&gt;Trying to programmatically execute &lt;code&gt;local&lt;/code&gt; as a process will fail - there is no executable with that name; it is purely a shell construct.&lt;/p&gt;
&lt;p&gt;So how do we know if a command is a builtin? The preferred method is to use the &lt;code&gt;type&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ type local
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;local is a shell builtin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;type&lt;/code&gt; command (which is &lt;em&gt;itself&lt;/em&gt; a builtin!) can tell you the exact type of shell command.&lt;/p&gt;
&lt;p&gt;Interestingly, you might be using more builtins than you think. &lt;code&gt;echo&lt;/code&gt; is a program, but most of the time you are not executing it when you are in a shell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ type -a echo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo is a shell builtin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo is /bin/echo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By using the &lt;code&gt;-a&lt;/code&gt; flag on &lt;code&gt;type&lt;/code&gt; to show &lt;em&gt;all&lt;/em&gt; commands that match the name, we see that &lt;code&gt;echo&lt;/code&gt; is actually both a builtin &lt;em&gt;and&lt;/em&gt; a program.&lt;/p&gt;
&lt;p&gt;Many simple programs have builtin versions. The shell can execute them much faster.&lt;/p&gt;
&lt;p&gt;Some commands are a builtin so that they can function in a sensible manner. The &lt;code&gt;cd&lt;/code&gt; command changes the current directory - if we executed it as a process, it would change only the directory for the &lt;code&gt;cd&lt;/code&gt; process itself, not the shell, making it much less useful.&lt;/p&gt;
&lt;p&gt;Builtins will vary from shell to shell, but many shells are &amp;lsquo;Bash-like&amp;rsquo; - meaning they will have a set very similar to the Bash builtins, which you can see here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html"&gt;https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As should be familiar from &lt;a href="https://www.dwmkerr.com/effective-shell-part-3-getting-hepl/"&gt;Part 3: Getting Help&lt;/a&gt;, you can get help for builtins:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ man source &lt;span style="color:#75715e"&gt;# source is a builtin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BUILTIN&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&gt;)&lt;/span&gt; BSD General Commands Manual BUILTIN&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; builtin, !, %, &lt;span style="color:#75715e"&gt;# ...snip...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SYNOPSIS
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; builtin &lt;span style="color:#f92672"&gt;[&lt;/span&gt;-options&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;args ...&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, the manual will &lt;em&gt;not&lt;/em&gt; show information on specific builtins, which is a pain. Your shell &lt;em&gt;might&lt;/em&gt; have an option to show more details - for example, in Bash you can use &lt;code&gt;help&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ help source
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source: source filename &lt;span style="color:#f92672"&gt;[&lt;/span&gt;arguments&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Read and execute commands from FILENAME and &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;. The pathnames
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; in $PATH are used to find the directory containing FILENAME. If any
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ARGUMENTS are supplied, they become the positional parameters when
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; FILENAME is executed.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But remember: &lt;code&gt;help&lt;/code&gt; is a builtin; you might not find it in all shells (you won&amp;rsquo;t find it in &lt;code&gt;zsh&lt;/code&gt;, for example). This highlights again the challenges of builtins.&lt;/p&gt;
&lt;h2 id="functions"&gt;Functions&lt;/h2&gt;
&lt;p&gt;You can define your own shell functions. We will see a lot more of this later, but let&amp;rsquo;s show a quick example for now:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ restart-shell &lt;span style="color:#f92672"&gt;()&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt; exec -l &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$SHELL&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This snippet creates a function that restarts the shell (quite useful if you are messing with shell configuration files or think you might have irreversibly goofed up your current session).&lt;/p&gt;
&lt;p&gt;We can execute this function just like any command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ restart-shell
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And running &lt;code&gt;type&lt;/code&gt; will show us that this is a function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ type restart-shell
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;restart-shell is a &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;restart-shell &lt;span style="color:#f92672"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exec -l $SHELL
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Functions are one of the most powerful shell constructs we will see; they are extremely useful for building sophisticated logic. We&amp;rsquo;re going to see them in a lot more detail later, but for now it is enough to know that they exist, and can run logic, and are run as commands.&lt;/p&gt;
&lt;h2 id="aliases"&gt;Aliases&lt;/h2&gt;
&lt;p&gt;An alias is just a shortcut. Type in a certain set of characters, and the shell will replace them with the value defined in the alias.&lt;/p&gt;
&lt;p&gt;Some common commands are actually already aliases - for example, in my &lt;code&gt;zsh&lt;/code&gt; shell, the &lt;code&gt;ls&lt;/code&gt; command is an alias:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% type -a ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls is an alias &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; ls -G
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls is /bin/ls
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I make sure that when I use the &lt;code&gt;ls&lt;/code&gt; command, the shell always expands it to &lt;code&gt;ls -G&lt;/code&gt;, which colours the output.&lt;/p&gt;
&lt;p&gt;We can quickly define aliases to save on keystrokes. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ alias k&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;kubectl&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From this point on, I can use the &lt;code&gt;k&lt;/code&gt; alias as shorthand for the &lt;code&gt;kubectl&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;Aliases are far less sophisticated than functions. Think of them as keystroke savers and nothing more, and you won&amp;rsquo;t go far wrong. Aliases are not portable across shells and have certain behaviours which can make them problematic to work with, there will be an entire chapter dedicated to alisases coming up in the series.&lt;/p&gt;
&lt;h2 id="so-what"&gt;So What?&lt;/h2&gt;
&lt;p&gt;So we now hopefully have a greater understanding of the variety of shell commands. Not all commands are executables, not all of the commands we &lt;em&gt;think&lt;/em&gt; are executables necessarily are, and some commands might be more sophisticated.&lt;/p&gt;
&lt;p&gt;As a shell user, the key things to remember are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Executables are &amp;lsquo;safe&amp;rsquo; - they are programs your system can use; your shell just calls out to them.&lt;/li&gt;
&lt;li&gt;Builtins are &lt;em&gt;very&lt;/em&gt; shell-specific and usually control the shell itself&lt;/li&gt;
&lt;li&gt;Functions are powerful ways to write logic but will normally be shell-specific.&lt;/li&gt;
&lt;li&gt;Aliases are conveniences for human operators, but only in the context of an interactive shell.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To find out how a command is implemented, just use the &lt;code&gt;type -a&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ type -a cat
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat is /bin/cat
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="more-than-you-need-to-know"&gt;More than You Need to Know&lt;/h2&gt;
&lt;p&gt;OK, for the masochistic few, you might be wondering about all of the other commands and utilities you may have seen that can tell you about programs and commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;what&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;whatis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;which&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;whence&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;where&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;whereis&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;command&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A &lt;em&gt;lot&lt;/em&gt; of these are legacy and should be avoided, but for completeness sake, we&amp;rsquo;ll go through them.&lt;/p&gt;
&lt;h3 id="what"&gt;&lt;code&gt;what&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;what&lt;/code&gt; reads out special metadata embedded in a program, generally used to identify the version of source code it was built from:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ what /bin/ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/bin/ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Copyright &lt;span style="color:#f92672"&gt;(&lt;/span&gt;c&lt;span style="color:#f92672"&gt;)&lt;/span&gt; 1989, 1993, &lt;span style="color:#ae81ff"&gt;1994&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; PROGRAM:ls PROJECT:file_cmds-272.220.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There should be almost no circumstance in which you need to use it in your day-to-day work, but you might come across it if you &lt;em&gt;meant&lt;/em&gt; to type &lt;code&gt;whatis&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="whatis"&gt;&lt;code&gt;whatis&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;whatis&lt;/code&gt; searches a local help database for text. This can be useful in tracking down manual pages:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ whatis bash
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bash&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&gt;)&lt;/span&gt; - GNU Bourne-Again SHell
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bashbug&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&gt;)&lt;/span&gt; - report a bug in bash
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But I can&amp;rsquo;t imagine it will be a regularly used tool by most users.&lt;/p&gt;
&lt;h3 id="which"&gt;&lt;code&gt;which&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;which&lt;/code&gt; will search your &lt;code&gt;$PATH&lt;/code&gt; to see whether an executable can be found. With the &lt;code&gt;-a&lt;/code&gt; flag, it will show all results.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ which -a vi
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/local/bin/vi
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/bin/vi
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;which&lt;/code&gt; originated in &lt;code&gt;csh&lt;/code&gt;. It remains on many systems for compatibility but in general should be avoided due to potentially odd behaviour&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id="whence"&gt;&lt;code&gt;whence&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;whence&lt;/code&gt; was added to the Korn shell. You are unlikely to use it unless you are on systems using &lt;code&gt;ksh&lt;/code&gt;. &lt;code&gt;zsh&lt;/code&gt; also has this command, but it should be avoided and considered non-standard.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% whence brew
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/local/bin/brew
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="where"&gt;&lt;code&gt;where&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;This is a shell builtin that can provide information on commands, similar to &lt;code&gt;type&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% where ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls: aliased to ls -G
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/bin/ls
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, &lt;code&gt;type&lt;/code&gt; should be preferred, as it is more standard.&lt;/p&gt;
&lt;h3 id="whereis"&gt;&lt;code&gt;whereis&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;whereis&lt;/code&gt; is available on some systems and generally operates the same as &lt;code&gt;which&lt;/code&gt;, searching paths for an executable:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% whereis ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/bin/ls
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, &lt;code&gt;type&lt;/code&gt; should be preferred for compatability.&lt;/p&gt;
&lt;h3 id="command"&gt;&lt;code&gt;command&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;command&lt;/code&gt; is defined in the POSIX standard, so should be expected to be present on most modern systems. Without arguments, it simply executes a command. With the &lt;code&gt;-v&lt;/code&gt; argument, you get a fairly machine-readable or processable response; with the &lt;code&gt;-V&lt;/code&gt; argument, you get a more human readable response:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% command -v ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;alias ls&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;ls -G&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% command -V ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls is an alias &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; ls -G
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;command&lt;/code&gt; can be useful in scripts, as we will see in later chapters.&lt;/p&gt;
&lt;h3 id="type"&gt;&lt;code&gt;type&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;type&lt;/code&gt; is part of the Unix standard and will be present in most modern systems. As we&amp;rsquo;ve already seen, it will identify the type of command as well as the location for an executable:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% type -a ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls is an alias &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; ls -G
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls is /bin/ls
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This command can also be used to only search for paths:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% type -p ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls is /bin/ls
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In summary, avoid anything that starts with &amp;lsquo;&lt;code&gt;w&lt;/code&gt;&amp;rsquo;! These are legacy commands, generally needed only when working on older Unix machines. &lt;code&gt;type&lt;/code&gt; or &lt;code&gt;command&lt;/code&gt; should be used instead.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Footnotes&lt;/strong&gt;&lt;/p&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;We will cover permissions and modes in later chapters.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Why these names and locations? It&amp;rsquo;s a long story. The best place to start if you are intersted is the &lt;a href="https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard"&gt;Filesystem Hierarchy Standard&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;&lt;code&gt;chmod&lt;/code&gt; changes the mode of a file; &lt;code&gt;+x&lt;/code&gt; means &amp;lsquo;add the executable bit&amp;rsquo;. This tells the operating system the file can be executed.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://unix.stackexchange.com/questions/85249/why-not-use-which-what-to-use-then"&gt;Stack Exchange: Why not use “which”? What to use then?&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><category>CodeProject</category></item><item><title>Effective Shell Part 6: Everything You Don't Need To Know About Job Control</title><link>https://dwmkerr.com/effective-shell-6-job-control/</link><pubDate>Mon, 10 Jun 2019 08:26:33 +0000</pubDate><guid>https://dwmkerr.com/effective-shell-6-job-control/</guid><description>&lt;p&gt;&lt;em&gt;Job control&lt;/em&gt; is a feature of most shells, which is generally not particularly intuitive to work with. However, knowing the basics can help prevent you from getting yourself into a tangle, and can from time to time make certain tasks a little easier.&lt;/p&gt;
&lt;p&gt;In this chapter, we&amp;rsquo;ll look at the main features of job control, why it can be a problematic, and some alternatives.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.dwmkerr.com/effective-shell-part-1-navigating-the-command-line/"&gt;Part 1: Navigating the Command Line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dwmkerr.com/effective-shell-part-2-become-a-clipboard-gymnast/"&gt;Part 2: Become a Clipboard Gymnast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dwmkerr.com/effective-shell-part-3-getting-hepl/"&gt;Part 3: Getting Help&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dwmkerr.com/effective-shell-4-moving-around/"&gt;Part 4: Moving Around&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dwmkerr.com/effective-shell-part-5-understanding-the-shell/"&gt;Part 5: Interlude - Understanding the Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dwmkerr.com/effective-shell-6-job-control/"&gt;Part 6: Everything You Don&amp;rsquo;t Need to Know About Job Control&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dwmkerr.com/effective-shell-7-shell-commands/"&gt;Part 7: The Subtleties of Shell Commands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-is-job-control"&gt;What Is Job Control?&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start with an example. I am building a simple web page. It has one &lt;code&gt;index.html&lt;/code&gt; file, one &lt;code&gt;styles.css&lt;/code&gt; file, and one &lt;code&gt;code.js&lt;/code&gt; file. The &lt;code&gt;index.html&lt;/code&gt; file looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;My New Project&amp;lt;/&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rel&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;stylesheet&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;text/css&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;styles.css&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;code.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;!-- Snip... --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Opening the file in a browser doesn&amp;rsquo;t quite work, as it won&amp;rsquo;t load the code or the styles. We need a web server to serve styles and code.&lt;/p&gt;
&lt;p&gt;A super-useful one-liner to run a web server on any machine with Python installed is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In fact, this is so useful that I normally &lt;em&gt;alias&lt;/em&gt; this command, so that I can just type &lt;code&gt;serve&lt;/code&gt;. We&amp;rsquo;ll see aliases in a later chapter.&lt;/p&gt;
&lt;p&gt;For now, if we run this command (you can get &lt;a href="https://github.com/dwmkerr/effective-shell/tree/master/6-job-control/sample"&gt;the three sample files here&lt;/a&gt; if you want to try this yourself), then we can open the webpage in a browser, with the styles and code loaded:&lt;/p&gt;
&lt;img src="images/website-screenshot.png" alt="Screenshot: Website" width="600" /&gt;
&lt;p&gt;We can also see that the server has served the HTML, JavaScript, and CSS files:&lt;/p&gt;
&lt;img src="images/server-screenshot.png" alt="Screenshot: Server" width="600" /&gt;
&lt;p&gt;All well and good so far.&lt;/p&gt;
&lt;h2 id="the-problem"&gt;The Problem&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say we want to now continue using our shell, maybe to edit the website with a terminal editor like Vim or Emacs, or we want to zip up the site, or just run any shell command&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;We have a problem. The &lt;code&gt;python&lt;/code&gt; process is still running - it&amp;rsquo;s serving the website. Our shell is essentially useless, until we stop the server. See what happens when I try to edit a file:&lt;/p&gt;
&lt;img src="images/blocked-shell.gif" alt="Demo: Blocked Shell" width="600" /&gt;
&lt;p&gt;In the example above, I try to run &lt;code&gt;vi&lt;/code&gt;, but nothing is happening. Standard input is not being read by the server and not being interpreted by the shell.&lt;/p&gt;
&lt;p&gt;I have to kill the server by hitting &lt;code&gt;Ctrl+C&lt;/code&gt; (which sends a &lt;code&gt;SIGINT&lt;/code&gt;&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; - we&amp;rsquo;ll see more about signals later), clear my screen to get rid of all of the error messages, then start again.&lt;/p&gt;
&lt;p&gt;This is obviously not optimal. Let&amp;rsquo;s look at some solutions.&lt;/p&gt;
&lt;h2 id="solution-1-start-the-server-in-the-background"&gt;Solution 1: Start the Server in the Background&lt;/h2&gt;
&lt;p&gt;In most shells, you can run a command and instruct the shell to run it in the &lt;em&gt;background&lt;/em&gt;. To do this, you end the line with an ampersand. Here&amp;rsquo;s how the example would look in this case:&lt;/p&gt;
&lt;img src="images/start-in-background.gif" alt="Demo: Starting a Background Job" width="600" /&gt;
&lt;p&gt;By ending the command with an &lt;code&gt;&amp;amp;&lt;/code&gt; ampersand symbol, we instruct the shell to run the command as a &lt;em&gt;background job&lt;/em&gt;. This means that our shell is still functional. The shell has also notified us that this command is running as a background job with a specific &lt;em&gt;job number&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt; &amp;amp;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;19372&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In slightly obtuse language, the shell has informed us that it has started a job in the background, with job number &lt;code&gt;1&lt;/code&gt; and that this job is currently handling the process with ID &lt;code&gt;19372&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The ampersand solution is a fairly common pattern used in day-to-day work.&lt;/p&gt;
&lt;h2 id="solution-2-move-the-server-to-the-background"&gt;Solution 2: Move the Server to the Background&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you forgot to start the command in the background. Most likely in this case you&amp;rsquo;d kill the server with &lt;code&gt;Ctrl+C&lt;/code&gt; and then start it again with the &lt;code&gt;&amp;amp;&lt;/code&gt; option. However, what if this was a large file download or a task you didn&amp;rsquo;t want to abort?&lt;/p&gt;
&lt;p&gt;In the example below, we&amp;rsquo;ll move the job to the background:&lt;/p&gt;
&lt;img src="images/move-to-background.gif" alt="Demo: Moving a Job to the Background" width="600" /&gt;
&lt;p&gt;The process is currently in the foreground, so my shell is inactive. Hitting &lt;code&gt;Ctrl+Z&lt;/code&gt; sends a &amp;lsquo;suspend&amp;rsquo; signal to the process&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;, pausing it and moving it to the background.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s dissect this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Serving HTTP on 0.0.0.0 port &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;127.0.0.1 - - &lt;span style="color:#f92672"&gt;[&lt;/span&gt;03/Jun/2019 13:38:45&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;GET / HTTP/1.1&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt; -
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;^Z
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + &lt;span style="color:#ae81ff"&gt;21268&lt;/span&gt; suspended python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The shell echos as I type, so we see &lt;code&gt;^Z&lt;/code&gt; (i.e., the &lt;code&gt;Ctrl+Z&lt;/code&gt; chord I entered). The shell responds by moving the process into a background job and suspending it.&lt;/p&gt;
&lt;p&gt;The key here is that it is &lt;em&gt;suspended&lt;/em&gt;. The process is paused. So the web server is no longer serving. If you are following with the sample, reload your browser. The webpage fails to load, as the server process is not able to respond to requests.&lt;/p&gt;
&lt;p&gt;To &lt;em&gt;continue&lt;/em&gt; the job, in the background, we use the &lt;code&gt;bg&lt;/code&gt; (&amp;lsquo;background&amp;rsquo;) command, with a &lt;em&gt;job identifier&lt;/em&gt; (which always starts with a &lt;code&gt;%&lt;/code&gt; symbol - we&amp;rsquo;ll see why soon) to tell the shell to continue the job:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% bg %1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + &lt;span style="color:#ae81ff"&gt;21268&lt;/span&gt; continued python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The shell lets us know the job is being continued, and if we load the webpage again, the content is shown as expected.&lt;/p&gt;
&lt;p&gt;As a final check, we run the &lt;code&gt;jobs&lt;/code&gt; command to see what jobs the shell is running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% jobs
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + running python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And there you have it - our server is running as a background job. This is exactly what we would see if we run &lt;code&gt;jobs&lt;/code&gt; after starting the server with an &lt;code&gt;&amp;amp;&lt;/code&gt; at the end. In fact, using an &lt;code&gt;&amp;amp;&lt;/code&gt; is perhaps an easier way to remember how to continue a suspended job:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% %1 &amp;amp;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + &lt;span style="color:#ae81ff"&gt;21268&lt;/span&gt; continued python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the same way ending a command with &lt;code&gt;&amp;amp;&lt;/code&gt; runs it in the background, ending a job identifier with &lt;code&gt;&amp;amp;&lt;/code&gt; &lt;em&gt;continues&lt;/em&gt; it in the background.&lt;/p&gt;
&lt;p&gt;There is at least one more way to move a job to the background&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;, but I have not yet found it useful in any scenarios, and it is overly complex to explain. See the footnote for details if you are interested.&lt;/p&gt;
&lt;h2 id="moving-background-jobs-to-the-foreground"&gt;Moving Background Jobs to the Foreground&lt;/h2&gt;
&lt;p&gt;If you have a job in the background, you can bring it back to the foreground with the &lt;code&gt;fg&lt;/code&gt; (&amp;lsquo;foreground&amp;rsquo;) command. Let&amp;rsquo;s show the jobs, with the &lt;code&gt;jobs&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% jobs
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + running python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here I have a background job running a server. Any one of the following commands will bring it back to the foreground:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fg %1 &lt;span style="color:#75715e"&gt;# Explicitly bring Job 1 into the foreground&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;%1 &lt;span style="color:#75715e"&gt;# ...or in shorthand, just enter the job id...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fg &lt;span style="color:#75715e"&gt;# ...if not given an id, fg and bg assume the most recent job.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now the job is in the foreground, and you can interact with the process again however you like.&lt;/p&gt;
&lt;h2 id="cleaning-up-jobs"&gt;Cleaning Up Jobs&lt;/h2&gt;
&lt;p&gt;You might realise you cannot continue what you are doing because an old job is &lt;em&gt;still running&lt;/em&gt;. Here&amp;rsquo;s an example:&lt;/p&gt;
&lt;img src="images/kill-job.gif" alt="Demo: Cleaning Up Jobs" width="600" /&gt;
&lt;p&gt;I tried to run my web server, but there was still one running as a background job. The server failed to start because the port is in use.&lt;/p&gt;
&lt;p&gt;To clean it up, I run the &lt;code&gt;jobs&lt;/code&gt; command to list the jobs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% jobs
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + suspended python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s my old web server. Note that even though it is suspended, it&amp;rsquo;ll still be blocking the port it is serving on&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;. The process is paused, but it is still holding onto all of the resources it is using.&lt;/p&gt;
&lt;p&gt;Now that I know the job identifier (&lt;code&gt;%1&lt;/code&gt; in this case), I can kill the job:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;% kill %1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + &lt;span style="color:#ae81ff"&gt;22843&lt;/span&gt; terminated python -m SimpleHTTPServer &lt;span style="color:#ae81ff"&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;This is why job identifiers start with a percentage sign!&lt;/em&gt; The &lt;code&gt;kill&lt;/code&gt; command I have used is not a special job control command (like &lt;code&gt;bg&lt;/code&gt; or &lt;code&gt;fg&lt;/code&gt;). It is the normal &lt;code&gt;kill&lt;/code&gt; command, which terminates a process. But shells that support job control can normally use a job identifier in place of a &lt;em&gt;process identifier&lt;/em&gt;. So rather than working out what the process identifier is that I need to kill, I can just use the job identifier&lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id="why-you-shouldnt-use-jobs"&gt;Why You Shouldn&amp;rsquo;t Use Jobs&lt;/h2&gt;
&lt;p&gt;Avoid jobs. They are not intuitive to interface with, and they suffer from some serious problems.&lt;/p&gt;
&lt;p&gt;The most obvious one is that all jobs write to the same output, meaning you can quickly get garbled output like this:&lt;/p&gt;
&lt;img src="images/output.png" alt="Screenshot: Garbled Output" width="600" /&gt;
&lt;p&gt;This is what happens when I run a job, which just outputs text every second. It&amp;rsquo;s in the background, but it&amp;rsquo;s printing all over my commands. Even running the &lt;code&gt;jobs&lt;/code&gt; command to try and find the job to stop it is difficult.&lt;/p&gt;
&lt;p&gt;Input is even more complex. If a job is &lt;em&gt;running&lt;/em&gt; in the background, but requires input, it will be &lt;em&gt;silently suspended&lt;/em&gt;. This can cause confusion.&lt;/p&gt;
&lt;p&gt;Jobs &lt;em&gt;can&lt;/em&gt; be used in scripts but must be done so with caution and could easily confuse a consumer of the script if they leave background jobs hanging around, which cannot be easily cleaned up&lt;sup id="fnref:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Handling errors and exit codes for jobs can be problematic, causing confusion, poor error handling, or overly complex code.&lt;/p&gt;
&lt;h2 id="how-to-escape-jobs"&gt;How to Escape Jobs&lt;/h2&gt;
&lt;p&gt;If there are two things to take away, it would be this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you have started running a command in the foreground, and you don&amp;rsquo;t want to stop it and would rather move it to the background, hit &lt;code&gt;Ctrl+Z&lt;/code&gt;. Then Google &amp;ldquo;job control&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you think there is a job running in the background, and it is messing with your screen, type &lt;code&gt;fg&lt;/code&gt; to bring it to the front and kill it with &lt;code&gt;Ctrl+C&lt;/code&gt;. Repeat as needed!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In either case, if you need to do something more subtle, you can return to this reference. But the first command should allow you to get your shell back while you work out how to continue the job, and the second should kill a background job that is messing with your screen.&lt;/p&gt;
&lt;h2 id="alternatives-to-jobs"&gt;Alternatives to Jobs&lt;/h2&gt;
&lt;p&gt;If you are using any kind of modern terminal such as iTerm, Terminal or the GNOME Terminal, just open a new tab or split! Much easier.&lt;/p&gt;
&lt;p&gt;The benefit to this is that each tab gets its own standard input and output, so there&amp;rsquo;s no risk of overwriting. And of course you can hide/reveal/rearrange the tabs however you like.&lt;/p&gt;
&lt;p&gt;The traditional alternative to a job for an operator who simply wants more than one thing going on at once would be a &lt;em&gt;terminal multiplexer&lt;/em&gt;, such as &lt;code&gt;screen&lt;/code&gt; or &lt;code&gt;tmux&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="images/terminal-multiplexer.gif" alt="terminal-multiplexer"&gt;&lt;/p&gt;
&lt;p&gt;Multiplexers work in a very similar way to a modern graphical terminal - they manage many shell instances. The benefits to a modern terminal, such as iTerm, is that you have a very intuitive GUI and lots of features.&lt;/p&gt;
&lt;p&gt;The benefits to a multiplexer are that you can run them over SSH sessions to manage complex operations on remote machines and that they run a client-server model, meaning many people can work with many multiplexed processes (and they can persist beyond sessions).&lt;/p&gt;
&lt;p&gt;My personal preference is both - I use a modern terminal &lt;em&gt;and&lt;/em&gt; run everything inside it in &lt;code&gt;tmux&lt;/code&gt;. We&amp;rsquo;ll look at both of these options in later chapters.&lt;/p&gt;
&lt;h2 id="quick-reference"&gt;Quick Reference&lt;/h2&gt;
&lt;p&gt;You might find that jobs are useful, or you might find that they are not. Either way, here&amp;rsquo;s a quick reference of some common commands:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;command &amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run the command as a background job.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;Ctrl+Z&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Move the current process into a background job, suspended.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;jobs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all jobs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fg %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Move background job number 1 into the foreground.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bg %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Continue background job number 1.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kill %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Terminate job number 1.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wait %1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Block until job number 1 exits.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you want to find out more about the gory details of jobs, the best place to start is the &lt;a href="https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Job-Control"&gt;Bash Manual - Job Control Section&lt;/a&gt;, or the &amp;lsquo;Job Control&amp;rsquo; section of your preferred shell&amp;rsquo;s manual.&lt;/p&gt;
&lt;p&gt;I hope you found this useful, and, as always, please leave comments, questions or suggestions below!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="footnotes"&gt;Footnotes&lt;/h2&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;If you are not a heavy shell user, this might seem unlikely. But if you do a lot of work in shells, such as sysadmin, devops, or do your coding from a terminal, this happens all the time!&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Signals like &lt;code&gt;SIGINT&lt;/code&gt;, &lt;code&gt;SIGKILL&lt;/code&gt;, &lt;code&gt;SIGTERM&lt;/code&gt; and so on will be covered in a later chapter.&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Technically, &lt;code&gt;SIGTSTP&lt;/code&gt; - which is &amp;lsquo;TTY stop&amp;rsquo;. If you have always wondered about the &amp;lsquo;TTY&amp;rsquo; acroynm, check the previous chatper, &lt;a href="https://dwmkerr.com/effective-shell-part-5-understanding-the-shell/"&gt;Interlude: Understanding the Shell&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;The alternative method is to use &lt;code&gt;Ctrl+Y&lt;/code&gt;, which will send a &lt;em&gt;delayed interrupt&lt;/em&gt;, which will continue to run the process until it tries to read from &lt;code&gt;stdin&lt;/code&gt;. At this point, the job is suspended and the control given to the shell. The operator can then use &lt;code&gt;bg&lt;/code&gt; or &lt;code&gt;kill&lt;/code&gt; or &lt;code&gt;fg&lt;/code&gt; to either move to the background, stop the process, or keep in the foreground as preferred. See: &lt;a href="https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Job-Control"&gt;https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Job-Control&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Another super-useful snippet: &lt;code&gt;lsof -i -P -n | grep 8000&lt;/code&gt; to find any process that has a given port open. Another one for the aliases chapter!&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;There are times this is needed. If a job runs &lt;em&gt;many processes&lt;/em&gt; - for example, by running a pipeline - the process identifier will change as the command moves from one stage of the pipeline to the next. The job identifier will remain constant. Remember, a job is a shell &lt;em&gt;command&lt;/em&gt;, so could run many processes.&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;To see how bad this can be, create a script that starts jobs, then run it. Then run the &lt;code&gt;jobs&lt;/code&gt; command to see what is running. The output might surprise you!&amp;#160;&lt;a href="#fnref:7" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><category>CodeProject</category></item></channel></rss>