<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:og="http://ogp.me/ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:schema="http://schema.org/" xmlns:sioc="http://rdfs.org/sioc/ns#" xmlns:sioct="http://rdfs.org/sioc/types#" xmlns:skos="http://www.w3.org/2004/02/skos/core#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" version="2.0" xml:base="https://www.linuxjournal.com/">
  <channel>
    <title>Bash</title>
    <link>https://www.linuxjournal.com/</link>
    <description/>
    <language>en</language>
    
    <item>
  <title>Boost Up Productivity in Bash - Tips and Tricks</title>
  <link>https://www.linuxjournal.com/content/boost-productivity-bash-tips-and-tricks</link>
  <description>  &lt;div data-history-node-id="1340818" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/antonio-riso" lang="" about="https://www.linuxjournal.com/users/antonio-riso" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Antonio Riso&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;When spending most of your day around bash shell, it is not uncommon to waste time typing the same commands over and over again. This is pretty close to the definition of insanity.&lt;/p&gt;

&lt;p&gt;Luckily, bash gives us several ways to avoid repetition and increase productivity.&lt;/p&gt;

&lt;p&gt;Today, we will explore the tools we can leverage to optimize what I love to call “shell time”.&lt;/p&gt;

&lt;h2&gt;Aliases&lt;/h2&gt;

&lt;p&gt;Bash aliases are one of the methods to define custom or override default commands.&lt;/p&gt;

&lt;p&gt;You can consider an alias as a “shortcut” to your desired command with options included.&lt;/p&gt;

&lt;p&gt;Many popular Linux distributions come with a set of predefined aliases.&lt;/p&gt;

&lt;p&gt;Let’s see the default aliases of Ubuntu 20.04, to do so simply type “alias” and press [ENTER].&lt;/p&gt;

&lt;p&gt;&lt;img alt="Image removed." data-entity-type="file" data-entity-uuid="7cc66a98-421e-4bfe-9ee6-ae237adc596e" height="16" src="https://www.linuxjournal.com/core/misc/icons/e32700/error.svg" width="16" title="This image has been removed. For security reasons, only images from the local domain are allowed." class="filter-image-invalid" /&gt;&lt;/p&gt;

&lt;p&gt;By simply issuing the command “l”, behind the scenes, bash will execute “ls -CF”.&lt;/p&gt;

&lt;p&gt;It's as simple as that.&lt;/p&gt;

&lt;p&gt;This is definitely nice, but what if we could specify our own aliases for the most used commands?! The answer is, of course we can!&lt;/p&gt;

&lt;p&gt;One of the commands I use extremely often is “cd ..” to change the working directory to the parent folder. I have spent so much time hitting the same keys…&lt;/p&gt;

&lt;p&gt;One day I decided it was enough and I set up an alias!&lt;/p&gt;

&lt;p&gt;To create a new alias type “alias ” the alias name, in my case I have chosen “..” followed by “=” and finally the command we want an alias for enclosed in single quotes.&lt;/p&gt;

&lt;p&gt;Here is an example below.&lt;/p&gt;

&lt;p&gt;&lt;img alt="Image removed." data-entity-type="file" data-entity-uuid="60b74a21-f8e8-4dfd-ad05-ed8005517172" height="16" src="https://www.linuxjournal.com/core/misc/icons/e32700/error.svg" width="16" title="This image has been removed. For security reasons, only images from the local domain are allowed." class="filter-image-invalid" /&gt;&lt;/p&gt;

&lt;h2&gt;Functions&lt;/h2&gt;

&lt;p&gt;Sometimes you will have the need to automate a complex command, perhaps accept arguments as input. Under these constraints, aliases will not be enough to accomplish your goal, but no worries. There is always a way out!&lt;/p&gt;

&lt;p&gt;Functions give you the ability to create complex custom commands which can be called directly from the terminal like any other command.&lt;/p&gt;

&lt;p&gt;For instance, there are two consecutive actions I do all the time, creating a folder and then cd into it. To avoid the hassle of typing “mkdir newfolder” and then “cd newfolder” i have create a bash function called “mkcd” which takes the name of the folder to be created as argument, create the folder and cd into it.&lt;/p&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/boost-productivity-bash-tips-and-tricks" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Wed, 16 Dec 2020 21:45:00 +0000</pubDate>
    <dc:creator>Antonio Riso</dc:creator>
    <guid isPermaLink="false">1340818 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>Writing GitHub Web Hooks with Bash</title>
  <link>https://www.linuxjournal.com/content/writing-github-web-hooks-bash</link>
  <description>  &lt;div data-history-node-id="1340749" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/andy-carlson" lang="" about="https://www.linuxjournal.com/users/andy-carlson" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Andy Carlson&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt;&lt;em&gt;Bring your GitHub repository to the next level of functionality.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;
For the past year since Microsoft has acquired GitHub, I've been hosting
my Git repositories on a private server. Although I relished the opportunity
and challenge of setting it all up, and the end product works well for my
needs, doing this was not without its sacrifices. GitHub offers a clean interface
for configuring many Git features that otherwise would require more time and
effort than simply clicking a button. One of the features made easier to
implement by GitHub that I was most fond of was web hooks.
A web hook is
executed when a specific event occurs within the GitHub application. Upon
execution, data is sent via an &lt;code&gt;HTTP POST&lt;/code&gt; to a specified URL.
&lt;/p&gt;

&lt;p&gt;
This article
walks through how to set up a custom web hook, including configuring a
web server, processing the POST data from GitHub and creating a few basic
web hooks using Bash.
&lt;/p&gt;

&lt;span class="h3-replacement"&gt;
Preparing Apache&lt;/span&gt;

&lt;p&gt;
For the purpose of this project, let's use the Apache web server to host
the web hook scripts. The module that Apache uses to run server-side shell
scripts is &lt;code&gt;mod_cgi&lt;/code&gt;, which is available on major Linux distributions.
&lt;/p&gt;

&lt;p&gt;
Once
the module is enabled, it's time to configure the directory permissions and
virtual host within Apache. Use the /opt/hooks directory to host the
web hooks, and give ownership of this directory to the
user that runs Apache. To determine the user running an Apache instance,
run the following command (provided Apache is currently running):

&lt;/p&gt;&lt;pre&gt;
&lt;code&gt;
ps -e -o %U%c| grep 'apache2\|httpd'
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;
These commands will return a two-column output containing the name of the
user running Apache and the name of the Apache binary (typically either
&lt;code&gt;httpd&lt;/code&gt; or &lt;code&gt;apache2&lt;/code&gt;). Grant directory
permission with the following
&lt;code&gt;chown&lt;/code&gt; command (where &lt;code&gt;USER&lt;/code&gt; is the name of the
user shown in the previous &lt;code&gt;ps&lt;/code&gt; command):

&lt;/p&gt;&lt;pre&gt;
&lt;code&gt;
chown -R USER /opt/hooks
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;
Within this directory, two sub-directories will be created: html and
cgi-bin. The html folder will be used as a web root for the virtual host,
and cgi-bin will contain all shell scripts for the virtual host. Be aware
that as new sub-directories and files are created under /opt/hooks, you
may need to rerun the
above &lt;code&gt;chown&lt;/code&gt; to verify proper access to files
and sub-directories.
&lt;/p&gt;

&lt;p&gt;
Here's the configuration for the virtual host within
Apache:

&lt;/p&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/writing-github-web-hooks-bash" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Wed, 07 Aug 2019 16:30:00 +0000</pubDate>
    <dc:creator>Andy Carlson</dc:creator>
    <guid isPermaLink="false">1340749 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>The Bash Trap Command</title>
  <link>https://www.linuxjournal.com/content/bash-trap-command</link>
  <description>  &lt;div data-history-node-id="1340787" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/mitch-frazier" lang="" about="https://www.linuxjournal.com/users/mitch-frazier" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Mitch Frazier&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt; &lt;/p&gt;
&lt;p&gt;If you've written any amount of bash code, you've likely come across the &lt;tt class="docutils literal"&gt;trap&lt;/tt&gt; command. Trap allows you to catch signals and execute code when they occur. Signals are asynchronous notifications that are sent to your script when certain events occur. Most of these notifications are for events that you hope never happen, such as an invalid memory access or a bad system call. However, there are one or two events that you might reasonably want to deal with. There are also "user" events available that are never generated by the system that you can generate to signal your script. Bash also provides a psuedo-signal called "EXIT", which is executed when your script exits; this can be used to make sure that your script executes some cleanup on exit.&lt;/p&gt;
&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/bash-trap-command" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Wed, 07 Aug 2019 15:15:00 +0000</pubDate>
    <dc:creator>Mitch Frazier</dc:creator>
    <guid isPermaLink="false">1340787 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>Bash Shell Games: Let's Play Go Fish!</title>
  <link>https://www.linuxjournal.com/content/bash-shell-games-lets-play-go-fish</link>
  <description>  &lt;div data-history-node-id="1340682" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/dave-taylor" lang="" about="https://www.linuxjournal.com/users/dave-taylor" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Dave Taylor&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt;&lt;em&gt;How to begin developing a computer version of the popular card game.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;
Between the previous 163 columns I've written here in &lt;em&gt;Linux Journal&lt;/em&gt; and the dozens
of games I programmed and explored during the creation of my &lt;em&gt;Wicked Cool
Shell Scripts&lt;/em&gt; book, I've written a lot of Bash shell games. The challenge is to
find one that's simple enough where a shell script will work, but isn't so
simple that it ends up being only a half-dozen lines.
&lt;/p&gt;

&lt;p&gt;
Magic 8-Ball is a perfect example. It turns out that the entire "predict the future" gizmo
was really just a 20-sided die floating in dark purple fluid. So an array of 20 possible
values and a random number selector and boom—you've got a magic 8-ball script:

&lt;/p&gt;&lt;pre&gt;
&lt;code&gt;
#!/bin/sh

# magic 8 ball. Yup. Pick a random number, output message

# messages harvested from the Wikipedia entry

answers=("It is certain." "It is decidedly so."
  "Without a doubt." "Yes - definitely."
  "You may rely on it." "As I see it, yes." "Most likely."
  "Outlook good." "Yes." "Signs point to yes."
  "Reply hazy, try again." "Ask again later."
  "Better not tell you now." "Cannot predict now."
  "Concentrate and ask again." "Don't count on it."
  "My reply is no." "My sources say no."
  "Outlook not so good." "Very doubtful.")

echo "Oh! Magic 8 Ball, Please Tell Me True..." ; echo ""
/bin/echo -n "What is your question? "
read question

answer=$(( $RANDOM % 20 ))

echo ""
echo "I have looked into the future and I say: "
echo "     ${answers[$answer]}" ; echo ""

exit 0
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;
Let's do a quick run to see if I'm the most popular &lt;em&gt;LJ&lt;/em&gt; writer:

&lt;/p&gt;&lt;pre&gt;
&lt;code&gt;
$ sh magic8.sh
Oh! Magic 8 Ball, Please Tell Me True...

What is your question? Am I the most popular LJ writer?

I have looked into the future and I say:
     My reply is no.
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;
Ouch, that's harsh. I write the darn divination program, and it just drops a brick on my foot.
Yeesh.
&lt;/p&gt;

&lt;p&gt;
More seriously, Magic 8 Ball is too simple to make an interesting shell script. By
contrast, &lt;em&gt;Call of Duty&lt;/em&gt; is way too complex, even if I did a version with text output
instead of gorgeously rendered 3D graphics.
&lt;/p&gt;

&lt;span class="h3-replacement"&gt;
Card Game Function Library&lt;/span&gt;

&lt;p&gt;
That's why card games prove to be good as programming challenges or exercises: the
core mechanism of a 52-card random deck is pretty straightforward, so it's all
about the actual cardplay.
&lt;/p&gt;

&lt;p&gt;
Not only that, but as I've written before about card games as shell scripts, I
already have a handy set of functions to create, shuffle and display cards out of a
deck. If you want to rummage in the archives, I've tackled &lt;em&gt;Acey-Deucey&lt;/em&gt;,
&lt;em&gt;Baccarat&lt;/em&gt;
and some bits and pieces of &lt;em&gt;Cribbage&lt;/em&gt;.
&lt;/p&gt;

&lt;p&gt;
In order to jump right into the new game that I'm going to describe how to build, &lt;em&gt;Go Fish!&lt;/em&gt;,
let's steal the following functions from my earlier scripts:
&lt;/p&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/bash-shell-games-lets-play-go-fish" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Tue, 30 Jul 2019 12:00:00 +0000</pubDate>
    <dc:creator>Dave Taylor</dc:creator>
    <guid isPermaLink="false">1340682 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>Job Control: the Bash Feature You Only Think You Don't Need</title>
  <link>https://www.linuxjournal.com/content/job-control-bash-feature-you-only-think-you-dont-need</link>
  <description>  &lt;div data-history-node-id="1340760" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/mitch-frazier" lang="" about="https://www.linuxjournal.com/users/mitch-frazier" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Mitch Frazier&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt;There are basically three types of people in the world: those who know little or nothing about bash job control, those who know enough to believe that it's nothing that they would ever use, and those who can just skim the rest of this post. Now, don't get me wrong, I'm not saying that bash's job control is going to change your world, but there are a couple simple everyday scenarios where job control can be useful, and often, it even can eliminate an "oh crap" moment.&lt;/p&gt;
&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/job-control-bash-feature-you-only-think-you-dont-need" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Thu, 25 Jul 2019 11:30:00 +0000</pubDate>
    <dc:creator>Mitch Frazier</dc:creator>
    <guid isPermaLink="false">1340760 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>Finishing Up the Bash Mail Merge Script</title>
  <link>https://www.linuxjournal.com/content/finishing-bash-mail-merge-script</link>
  <description>  &lt;div data-history-node-id="1340605" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/dave-taylor" lang="" about="https://www.linuxjournal.com/users/dave-taylor" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Dave Taylor&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt;&lt;em&gt;Finally, I'm going to finish the mail merge script, just in time for
Replicant Day.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;
Remember the &lt;a href="https://www.linuxjournal.com/content/fun-mail-merge-and-cool-bash-arrays"&gt;mail
merge script&lt;/a&gt; I started writing a while back? Yeah,
that was quite some
time ago. I got sidetracked with the &lt;em&gt;Linux Journal&lt;/em&gt; Anniversary special
issue (see my article &lt;a href="https://www.linuxjournal.com/content/back-day-unix-minix-and-linux"&gt;"Back
in the Day: UNIX, Minix and Linux"&lt;/a&gt;), and then I spun off on a
completely different tangent for my last article (&lt;a href="https://www.linuxjournal.com/content/breaking-apache-log-files-analysis"&gt;"Breaking
Up Apache Log Files for Analysis"&lt;/a&gt;). I blame it on...
&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;SQUIRREL!&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;
Oh, sorry, back to topic here. I was developing a shell
script that would let you specify a text document with
embedded field names that could be substituted iteratively
across a file containing lots of field values.
&lt;/p&gt;

&lt;p&gt;
Each field was denoted by &lt;code&gt;#fieldname#&lt;/code&gt;, and I identified two
categories of fieldnames: fixed and dynamic. A fixed value
might be &lt;code&gt;#name#&lt;/code&gt;, which would come directly out of the data
file, while a dynamic value could be &lt;code&gt;#date#&lt;/code&gt;, which would be
the current date.
&lt;/p&gt;
&lt;p&gt;
More interesting, I also proposed calculated values,
specifically &lt;code&gt;#suggested#&lt;/code&gt;, which would be a value calculated
based on &lt;code&gt;#donation#&lt;/code&gt;, and &lt;code&gt;#date#&lt;/code&gt;, which would be replaced by
the current date. The super-fancy version would have a
simple language where you could define the relationship between
variables, but let's get real. Mail merge. It's just mail
merge.
&lt;/p&gt;

&lt;span class="h3-replacement"&gt;
Reading and Assigning Values&lt;/span&gt;

&lt;p&gt;
It turns out that the additions needed for this script aren't
too difficult. The basic data file has comma-separated
field names, then subsequent lines have the values
associated with those fields.
&lt;/p&gt;

&lt;p&gt;
Here's that core code:

&lt;/p&gt;&lt;pre&gt;
&lt;code&gt;
if [ $lines -eq 1 ] ; then # field names
# grab variable names
declare -a varname=($f1 $f2 $f3 $f4 $f5 $f6 $f7)
else # process fields

# grab values for this line (can contain spaces)
declare -a value=("$f1" "$f2" "$f3" "$f4" "$f5" "$f6" "$f7")
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;
The &lt;code&gt;declare&lt;/code&gt; function turns out to be ideal for this,
allowing you to create an array &lt;code&gt;varname&lt;/code&gt; based on the
contents of the first line, then keep replacing the values
of the array &lt;code&gt;value&lt;/code&gt;, so that &lt;code&gt;varname[1] =
value[1]&lt;/code&gt;, and so
on.
&lt;/p&gt;

&lt;p&gt;
To add the additional variables &lt;code&gt;#date#&lt;/code&gt; and
&lt;code&gt;#suggested#&lt;/code&gt;, you
simply can append them to the &lt;code&gt;varname&lt;/code&gt; and
&lt;code&gt;value&lt;/code&gt; arrays. The
first one is easy, but it did highlight a weakness in the
original code that I had to fix by adding quotes as shown:

&lt;/p&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/finishing-bash-mail-merge-script" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Thu, 04 Jul 2019 12:00:00 +0000</pubDate>
    <dc:creator>Dave Taylor</dc:creator>
    <guid isPermaLink="false">1340605 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>What The @#$%&amp;! (Heck) is this #! (Hash-Bang) Thingy In My Bash Script</title>
  <link>https://www.linuxjournal.com/content/what-heck-hash-bang-thingy-my-bash-script</link>
  <description>  &lt;div data-history-node-id="1340624" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/mitch-frazier" lang="" about="https://www.linuxjournal.com/users/mitch-frazier" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Mitch Frazier&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt; &lt;/p&gt;
&lt;p&gt;You've seen it a million times—the hash-bang (#!) line at the top of a script—whether it be Bash, Python, Perl or some other scripting language. And, I'm sure you know what its purpose is: it specifies the script interpreter that's used to execute the script. But, do you know how it actually works? Your initial thought might be that your shell (bash) reads that line and then executes the specified interpreter, but that's not at all how it works. How it actually works is the main focus of this post, but I also want to introduce how you can create your own version of "hash-bang" if you're so inclined.&lt;/p&gt;
&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/what-heck-hash-bang-thingy-my-bash-script" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Fri, 10 May 2019 11:30:00 +0000</pubDate>
    <dc:creator>Mitch Frazier</dc:creator>
    <guid isPermaLink="false">1340624 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>Pattern Matching In Bash</title>
  <link>https://www.linuxjournal.com/content/pattern-matching-bash</link>
  <description>  &lt;div data-history-node-id="1340555" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/mitch-frazier" lang="" about="https://www.linuxjournal.com/users/mitch-frazier" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Mitch Frazier&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Wildcards have been around forever. Some even claim they appear in the hieroglyphics of the ancient Egyptians. Wildcards allow you to specify succinctly a pattern that matches a set of filenames (for example, &lt;tt class="docutils literal"&gt;*.pdf&lt;/tt&gt; to get a list of all the PDF files). Wildcards are also often referred to as glob patterns (or when using them, as "globbing"). But glob patterns have uses beyond just generating a list of useful filenames. The bash man page refers to glob patterns simply as "Pattern Matching".&lt;/p&gt;
&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/pattern-matching-bash" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Mon, 15 Apr 2019 11:30:00 +0000</pubDate>
    <dc:creator>Mitch Frazier</dc:creator>
    <guid isPermaLink="false">1340555 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>Fun with Mail Merge and Cool Bash Arrays</title>
  <link>https://www.linuxjournal.com/content/fun-mail-merge-and-cool-bash-arrays</link>
  <description>  &lt;div data-history-node-id="1340460" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/dave-taylor" lang="" about="https://www.linuxjournal.com/users/dave-taylor" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Dave Taylor&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt;&lt;em&gt;Creating a sed-based file substitution tool.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;
A few weeks ago, I was digging through my spam folder and found an email message
that started out like this:
&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;
Dear #name#
Congratulations on winning the $15.7 million lottery payout!
To learn how to claim your winnings, please...
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;
Obviously, it was a scam (does anyone actually fall for these?), but what captured my
attention was the &lt;code&gt;#name#&lt;/code&gt; sequence. Clearly that was a fail on the part of the sender who
presumably didn't know how to use AnnoyingSpamTool 1.3 or whatever the heck
he or she was using.
&lt;/p&gt;

&lt;p&gt;
The more general notation for bulk email and file transformations is pretty
interesting, however. There are plenty of legitimate reasons to use this sort
of substitution, ranging from email newsletters (like the one I send every week
from &lt;a href="https://www.askdavetaylor.com"&gt;AskDaveTaylor.com&lt;/a&gt;—check it out!) to stockholder announcements and much
more.
&lt;/p&gt;

&lt;p&gt;
With that as the inspiration, let's build a tool that offers just this
capability.
&lt;/p&gt;

&lt;p&gt;
The simple version will be a 1:1 substitution, so &lt;code&gt;#name#&lt;/code&gt; becomes, say,
"Rick Deckard", while &lt;code&gt;#first#&lt;/code&gt; might be "Rick" and
&lt;code&gt;#last#&lt;/code&gt; might
be "Deckard". Let's build on that, but let's start
small.
&lt;/p&gt;

&lt;span class="h3-replacement"&gt;
Simple Word Substitution in Linux&lt;/span&gt;

&lt;p&gt;
There are plenty of ways to tackle the word substitution from the command line,
ranging from Perl to awk, but here I'm using the original UNIX command
&lt;code&gt;sed&lt;/code&gt; (stream editor) designed for exactly this purpose. General notation for a
substitution is s/old/new/, and if you tack on a &lt;code&gt;g&lt;/code&gt; at the end, it
matches every occurrence on a line, not only the first, so the full command
is s/old/new/g.
&lt;/p&gt;

&lt;p&gt;
Before going further, here's a simple document that has necessary
substitutions embedded:

&lt;/p&gt;&lt;pre&gt;
&lt;code&gt;
$ cat convertme.txt
#date#

Dear #name#, I wanted to start by again thanking you for your
generous donation of #amount# in #month#. We couldn't do our
work without support from humans like you, #first#.

This year we're looking at some unexpected expenses,
particularly in Sector 5, which encompasses #state#, as you
know. I'm hoping you can start the year with an additional
contribution? Even #suggested# would be tremendously helpful.

Thanks for your ongoing support. With regards,

Rick Deckard
Society for the Prevention of Cruelty to Replicants
&lt;/code&gt;
&lt;/pre&gt;


&lt;p&gt;
Scan through it, and you'll see there's a lot of substitutions to do:
&lt;code&gt;#date#&lt;/code&gt;, &lt;code&gt;#name#&lt;/code&gt;,
&lt;code&gt;#amount#&lt;/code&gt;, &lt;code&gt;#month#&lt;/code&gt;, &lt;code&gt;#first#&lt;/code&gt;,
&lt;code&gt;#state#&lt;/code&gt; and &lt;code&gt;#suggested#&lt;/code&gt;. It turns out that
&lt;code&gt;#date#&lt;/code&gt; will
be replaced with the current date, and &lt;code&gt;#suggested#&lt;/code&gt; is one that'll be
calculated as the letter is processed, but that's for a bit later, so
stay tuned for that.
&lt;/p&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/fun-mail-merge-and-cool-bash-arrays" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Mon, 25 Mar 2019 11:30:00 +0000</pubDate>
    <dc:creator>Dave Taylor</dc:creator>
    <guid isPermaLink="false">1340460 at https://www.linuxjournal.com</guid>
    </item>
<item>
  <title>Cat-Proofing Your Screen Locker with Bash</title>
  <link>https://www.linuxjournal.com/content/cat-proofing-your-screen-locker</link>
  <description>  &lt;div data-history-node-id="1340483" class="layout layout--onecol"&gt;
    &lt;div class="layout__region layout__region--content"&gt;
      
            &lt;div class="field field--name-node-author field--type-ds field--label-hidden field--item"&gt;by &lt;a title="View user profile." href="https://www.linuxjournal.com/users/mitch-frazier" lang="" about="https://www.linuxjournal.com/users/mitch-frazier" typeof="schema:Person" property="schema:name" datatype="" xml:lang=""&gt;Mitch Frazier&lt;/a&gt;&lt;/div&gt;
      
            &lt;div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"&gt;&lt;p&gt; &lt;/p&gt;
&lt;p&gt;I have a computer in my bedroom. I also have cats. Unfortunately, cats and screen lockers don't mix well, particularly at night. To be accurate, it's more a problem with the display power management than the actual screen locking. Here's the way it works: I run a script to "shut the lights off at night" (that is, lock the screen and force the display to power down), and that works great, until one of the cats jumps on the desk and causes the mouse to move and turn the display back on. And the cats don't even have to touch the mouse; the slight movement of the desk is enough to cause the mouse to react. Recently, I'd had enough of it and figured there had to be a way to disable the mouse and "refactor" the script.&lt;/p&gt;
&lt;/div&gt;
      
            &lt;div class="field field--name-node-link field--type-ds field--label-hidden field--item"&gt;  &lt;a href="https://www.linuxjournal.com/content/cat-proofing-your-screen-locker" hreflang="en"&gt;Go to Full Article&lt;/a&gt;
&lt;/div&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;

</description>
  <pubDate>Wed, 20 Feb 2019 13:00:00 +0000</pubDate>
    <dc:creator>Mitch Frazier</dc:creator>
    <guid isPermaLink="false">1340483 at https://www.linuxjournal.com</guid>
    </item>

  </channel>
</rss>
