{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/motd/","result":{"data":{"markdownRemark":{"html":"<p>Occasional quotes and motivational messages sometimes give me a little boost, so I thought I’d tweak my shell to display a random message for the first terminal session of the day.</p>\n<h2>/etc/motd</h2>\n<p>Hard-coding something in <code>/etc/motd</code> would irritate me: it’d be the same message displayed again and again, in every terminal session. (<em>Well actually</em> it’d only be <a href=\"https://manpages.ubuntu.com/manpages/xenial/en/man1/login.1.html#files\">login sessions</a>, but that seems to be most interactive session across for me.)</p>\n<p>(Side-note: you can silence the <code>login</code> process by creating a <code>~/.hushlogin</code> file. i.e. <code>touch ~/.hushlogin</code> will suppress <code>/etc/motd</code> content in any/all login shells.)</p>\n<h2>/etc/update-motd.d/</h2>\n<p>A step up from a static <code>/etc/motd</code> file: Ubuntu and Debian support dynamic <a href=\"https://manpages.ubuntu.com/manpages/xenial/man5/update-motd.5.html#best%20practices\">motd fragments</a>, assembling a message from output of any number of executables in the <code>/etc/update-motd.d/</code> folder. I might have taken this approach if I was running an appropriate OS, but think it would still suffer from the same problem of displaying the message in every shell window.</p>\n<p>(Side-note: the executables in <code>/etc/update-motd.d/</code> run in lexixcal sort order; it’s common practice to give the executables numeric prefixes: e.g. <code>10-weather</code> would run before <code>99-scheduled-downtime</code>)</p>\n<h2>Simplified Requirements</h2>\n<p>I want:</p>\n<ol>\n<li>a repository of motiviational messages</li>\n<li>a record of the last time a message was displayed (<em>any</em> message)</li>\n</ol>\n<p>To keep things simple I’ll keep all the messages in a plain-text file, and use the last-modified timestamp of a sentinel file to record the ‘last displayed’ time.</p>\n<h2>Stealing content</h2>\n<p>I intend to carefully curate quotes that resonate with me, but for expediency I’ll grab some quotes in bulk from a couple of random articles.</p>\n<p>(I’m including these details as an example of extracting information direct from the DOM using Chrome’s devtools.)</p>\n<p>First up: <a href=\"https://www.success.com/17-motivational-quotes-to-inspire-you-to-be-successful/\">17 Motivational Quotes to Inspire You to Be Successful</a></p>\n<p>To extract the quotes I browsed the site in Chrome, opened devtools and used the Elements to check the structure of the page to identify container and structural elements used in the markup, then ran a snippet of code in the Console tab to get all the content into the clipboard.</p>\n<p>In this particular case all quotes were marked up as <code>h3</code> elements. I copied all the <code>h3</code> text content to the clipboard:</p>\n<pre class=\"grvsc-container default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk11\">copy</span><span class=\"mtk1\">(</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk10\">Array</span><span class=\"mtk1\">.</span><span class=\"mtk11\">from</span><span class=\"mtk1\">(</span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelectorAll</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;h3&quot;</span><span class=\"mtk1\">))</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(({ </span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> }) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">textContent</span><span class=\"mtk1\">)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">join</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">);</span></span></span></code></pre>\n<p>I used the CLI to filter out empty-lines (using <code>awk</code>), unwanted extra headings (using <code>head</code>) and stripped off an unwanted <code>number.</code> prefix from every quote (using <code>awk</code> again)</p>\n<pre class=\"grvsc-container default-dark\" data-language=\"bash\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\"># Ensure ~/.config/motd folder exists:</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">mkdir -p ~/.config/motd</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\"># Filter the clipboard data and append to the given file (the file will be created if it doesn&#39;t already exist.)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">pbpaste | awk NF | head -17 | awk </span><span class=\"mtk8\">&#39;{ sub(/^[^ ]+ /, &quot;&quot;) } 1&#39;</span><span class=\"mtk1\"> &gt;&gt; ~/.config/motd/messages</span></span></span></code></pre>\n<p>On reflection: shell commands were the wrong tool for the job. As we’re grabbing content from the web browser, we’d be better off doing the filtering and manipulation before copying the content to the clipboard:</p>\n<pre class=\"grvsc-container default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\">// Grab all quotes (and some unwanted noise)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk12\">quotes</span><span class=\"mtk1\"> = </span><span class=\"mtk10\">Array</span><span class=\"mtk1\">.</span><span class=\"mtk11\">from</span><span class=\"mtk1\">(</span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelectorAll</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;h3&quot;</span><span class=\"mtk1\">)).</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(({ </span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> }) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">textContent</span><span class=\"mtk1\">);</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\">// After inspecting results and trying various things in console, we quickly arrive at:</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk11\">copy</span><span class=\"mtk1\">(</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk12\">quotes</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">filter</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Boolean</span><span class=\"mtk1\">) </span><span class=\"mtk3\">// removes empty strings</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">slice</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">17</span><span class=\"mtk1\">) </span><span class=\"mtk3\">// only use content from the first 17 (non-empty) headings</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">map</span><span class=\"mtk1\">((</span><span class=\"mtk12\">quote</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">quote</span><span class=\"mtk1\">.</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">(</span><span class=\"mtk5\">/.</span><span class=\"mtk6\">*?</span><span class=\"mtk5\"> /</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">)) </span><span class=\"mtk3\">// strip off unwanted prefix</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">join</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">);</span></span></span></code></pre>\n<p>Second source: <a href=\"https://www.oberlo.co.uk/blog/motivational-quotes\">300 Motivational Quotes To Inspire You Today</a>.</p>\n<pre class=\"grvsc-container default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk12\">quotes</span><span class=\"mtk1\"> = </span><span class=\"mtk10\">Array</span><span class=\"mtk1\">.</span><span class=\"mtk11\">from</span><span class=\"mtk1\">(</span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelectorAll</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.single-post ol&gt;li&quot;</span><span class=\"mtk1\">)).</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  ({ </span><span class=\"mtk12\">textContent</span><span class=\"mtk1\"> }) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">textContent</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">);</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\">// After inspection, we believe all the content is clean, so no addigional filtering/processing required:</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk11\">copy</span><span class=\"mtk1\">(</span><span class=\"mtk12\">quotes</span><span class=\"mtk1\">.</span><span class=\"mtk11\">join</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">));</span></span></span></code></pre>\n<pre class=\"grvsc-container default-dark\" data-language=\"bash\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">pbpaste &gt;&gt; ~/.config/motd/messages</span></span></span></code></pre>\n<h2>The script</h2>\n<pre class=\"grvsc-container default-dark\" data-language=\"bash\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\">#!/bin/bash</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">CONFIG_DIR=~/.config/motd</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">MESSAGES=</span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">${CONFIG_DIR}</span><span class=\"mtk8\">/messages&quot;</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">MESSAGES_LAST_DISPLAY=</span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">${MESSAGES}</span><span class=\"mtk8\">-last-display&quot;</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> [ ! -f </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$MESSAGES</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> ]; </span><span class=\"mtk15\">then</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$0</span><span class=\"mtk8\">: Store messages in &#39;</span><span class=\"mtk12\">${MESSAGES}</span><span class=\"mtk8\">&#39; (file does not exist)&quot;</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">exit</span><span class=\"mtk1\"> 1</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">fi</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> [ ! -s </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$MESSAGES</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> ]; </span><span class=\"mtk15\">then</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$0</span><span class=\"mtk8\">: Cannot find any messages in &#39;</span><span class=\"mtk12\">${MESSAGES}</span><span class=\"mtk8\">&#39;&quot;</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">exit</span><span class=\"mtk1\"> 1</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">fi</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> [ ! -r </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$MESSAGES</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> ]; </span><span class=\"mtk15\">then</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$0</span><span class=\"mtk8\">: Cannot read messages from &#39;</span><span class=\"mtk12\">${MESSAGES}</span><span class=\"mtk8\">&#39; (file is not readable)&quot;</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">exit</span><span class=\"mtk1\"> 1</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">fi</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> [ -f </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$MESSAGES_LAST_DISPLAY</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> ]; </span><span class=\"mtk15\">then</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  TODAY=</span><span class=\"mtk8\">$(date +%F)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  LAST_DATE_DISPLAYED=</span><span class=\"mtk8\">$(date -r &quot;</span><span class=\"mtk12\">$MESSAGES_LAST_DISPLAY</span><span class=\"mtk8\">&quot; +%F)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> [ </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$TODAY</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> == </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$LAST_DATE_DISPLAYED</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> ]; </span><span class=\"mtk15\">then</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    </span><span class=\"mtk3\"># We already displayed a message today</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    </span><span class=\"mtk3\"># (One motivational message a day is enough)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">    </span><span class=\"mtk11\">exit</span><span class=\"mtk1\"> 0</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk15\">fi</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">fi</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\"># Get a random message from the file:</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">MESSAGE=</span><span class=\"mtk8\">$(shuf -n 1 &quot;</span><span class=\"mtk12\">$MESSAGES</span><span class=\"mtk8\">&quot; </span><span class=\"mtk1\">2&gt;</span><span class=\"mtk8\"> /dev/null)</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> [ -z </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$MESSAGE</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> ]; </span><span class=\"mtk15\">then</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">echo</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$0</span><span class=\"mtk8\">: Empty message (blank line) found in &#39;</span><span class=\"mtk12\">${MESSAGES}</span><span class=\"mtk8\">&#39;&quot;</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">  </span><span class=\"mtk11\">exit</span><span class=\"mtk1\"> 1</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk15\">fi</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\"># Using \\033 instead of \\e for escape codes as \\e wasn&#39;t working in iTerm on macOS</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk11\">echo</span><span class=\"mtk1\"> -e </span><span class=\"mtk8\">&quot;\\033[38;5;81m</span><span class=\"mtk12\">${MESSAGE}</span><span class=\"mtk8\">\\033[m&quot;</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\"># Create file or update its last-modified-time (mtime):</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk1\">touch </span><span class=\"mtk8\">&quot;</span><span class=\"mtk12\">$MESSAGES_LAST_DISPLAY</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\"> &amp;&gt; /dev/null</span></span></span></code></pre>\n<p>Also available as <a href=\"https://gist.github.com/ashsearle/bb815eb99b429c0a8ec46a5bc45d16a4\">a gist</a></p>\n<p>I called the script <code>motd</code> and stored it in <code>~/bin</code> (which is in my <code>PATH</code>.)</p>\n<p>As I reuse a <code>~/.bash_profile</code> between machines, I check whether the <code>motd</code> command exists before trying to execute it:</p>\n<pre class=\"grvsc-container default-dark\" data-language=\"bash\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk3\"># Run our motd command if-and-only-if it exists:</span></span></span>\n<span class=\"grvsc-line\"><span class=\"grvsc-source\"><span class=\"mtk11\">command</span><span class=\"mtk1\"> -v motd &amp;&gt; /dev/null &amp;&amp; motd</span></span></span></code></pre>\n<h2>Tidbits</h2>\n<ul>\n<li><code>date -r</code> allows you to get (and format) the last-modified data for a file - e.g. <code>date -r file +%F</code></li>\n<li>there’s a handy <code>copy()</code> function available in the console in Chrome devtools (and Safari, and Firefox.) (note: the browsers behave slightly differently if you try copying non-text content (such as arrays))</li>\n<li>terminal emulators may use/understand/require different escape sequence syntax: e.g. <code>\\e</code> vs <code>\\033</code></li>\n<li><code>~/.config/</code> is emerging as a bucket various tools use to store config (in their own named subfolder)</li>\n<li>use <code>command -v</code> to check if a command exists (I would have settled for <code>which</code>)</li>\n<li>use <code>&#x26;> filename</code> to redirect stdout <em>and</em> stderr to the same file (<a href=\"https://stackoverflow.com/a/24793436/98493\">this stackoverflow answer</a> has more info on redirection syntax)</li>\n<li>use <code>shuf</code> to select random lines from a file (see <a href=\"http://manpages.ubuntu.com/manpages/trusty/man1/shuf.1.html\">man page</a>)</li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    position: relative;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n    line-height: 1.4;\n  }\n  \n  .grvsc-code {\n    display: table;\n  }\n  \n  .grvsc-line {\n    display: table-row;\n    box-sizing: border-box;\n    width: 100%;\n    position: relative;\n  }\n  \n  .grvsc-line > * {\n    position: relative;\n  }\n  \n  .grvsc-gutter-pad {\n    display: table-cell;\n    padding-left: 0.75rem;\n    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);\n  }\n  \n  .grvsc-gutter {\n    display: table-cell;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n  }\n  \n  .grvsc-gutter::before {\n    content: attr(data-content);\n  }\n  \n  .grvsc-source {\n    display: table-cell;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-source:empty::after {\n    content: ' ';\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n  }\n  \n  .grvsc-gutter + .grvsc-source {\n    padding-left: 0.75rem;\n    padding-left: calc(var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem)) / 2);\n  }\n  \n  /* Line transformer styles */\n  \n  .grvsc-has-line-highlighting > .grvsc-code > .grvsc-line::before {\n    content: ' ';\n    position: absolute;\n    width: 100%;\n  }\n  \n  .grvsc-line-diff-add::before {\n    background-color: var(--grvsc-line-diff-add-background-color, rgba(0, 255, 60, 0.2));\n  }\n  \n  .grvsc-line-diff-del::before {\n    background-color: var(--grvsc-line-diff-del-background-color, rgba(255, 0, 20, 0.2));\n  }\n  \n  .grvsc-line-number {\n    padding: 0 2px;\n    text-align: right;\n    opacity: 0.7;\n  }\n  \n  .default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .default-dark .mtk11 { color: #DCDCAA; }\n  .default-dark .mtk1 { color: #D4D4D4; }\n  .default-dark .mtk10 { color: #4EC9B0; }\n  .default-dark .mtk12 { color: #9CDCFE; }\n  .default-dark .mtk8 { color: #CE9178; }\n  .default-dark .mtk4 { color: #569CD6; }\n  .default-dark .mtk6 { color: #D7BA7D; }\n  .default-dark .mtk3 { color: #6A9955; }\n  .default-dark .mtk7 { color: #B5CEA8; }\n  .default-dark .mtk5 { color: #D16969; }\n  .default-dark .mtk15 { color: #C586C0; }\n  .default-dark .grvsc-line-highlighted::before {\n    background-color: var(--grvsc-line-highlighted-background-color, rgba(255, 255, 255, 0.1));\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, rgba(255, 255, 255, 0.5));\n  }\n</style>","timeToRead":5,"frontmatter":{"title":"Motivational MOTD","blurb":"A small shell-script to output a motivational message-of-the-day - only once a day","date":"2020-11-11T18:50:07.471Z","modified":null}}},"pageContext":{"slug":"/blog/motd/","next":{"fields":{"slug":"/blog/run-jsx-from-command-line/"},"frontmatter":{"title":"Running .jsx from the command-line"}},"previous":{"fields":{"slug":"/blog/2009/12/03/javascript-date-to-time/"},"frontmatter":{"title":"JavaScript Date to Time"}}}},"staticQueryHashes":["1192980692"]}