<?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:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Xensoft]]></title><description><![CDATA[Linux, supercomputing, and technology.]]></description><link>https://xensoft.com/</link><image><url>https://xensoft.com/favicon.png</url><title>Xensoft</title><link>https://xensoft.com/</link></image><generator>Ghost 5.26</generator><lastBuildDate>Fri, 17 Apr 2026 08:41:32 GMT</lastBuildDate><atom:link href="https://xensoft.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Resize Virtualbox Ubuntu LVM Storage in MacOS]]></title><description><![CDATA[<p>I&apos;ve seen examples of how to accomplish this in Windows. The syntax is slightly different on MacOS. I also find the most straightforward way to do this is a little bit scary for those unfamiliar with Linux partitions. This should work on any LVM based *nix VM; I</p>]]></description><link>https://xensoft.com/resize-virtualbox-ubuntu-storage-in-macos/</link><guid isPermaLink="false">63b465ca952cee0339bb0585</guid><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Tue, 03 Jan 2023 17:52:10 GMT</pubDate><content:encoded><![CDATA[<p>I&apos;ve seen examples of how to accomplish this in Windows. The syntax is slightly different on MacOS. I also find the most straightforward way to do this is a little bit scary for those unfamiliar with Linux partitions. This should work on any LVM based *nix VM; I just happened to use it on my Ubuntu image.</p><p>Let&apos;s jump in.</p><!--kg-card-begin: markdown--><ol>
<li>Shutdown your VM</li>
<li>Detach existing Storage<br>
<img src="https://xensoft.com/content/images/2023/01/Screen-Shot-2023-01-03-at-9.35.26-AM.png" alt="Screen-Shot-2023-01-03-at-9.35.26-AM" loading="lazy"><br>
In your VMs settings for Storage select the SATA attached disk and click the &apos;remove&apos; icon below.</li>
<li>Find the location of the storage and run <code>VBoxManage</code> to resize, below resizes the disk image to 25GB:</li>
</ol>
<pre><code class="language-bash">VBoxManage modifymedium disk Ubuntu.vdi --resize 25000
</code></pre>
<ol start="4">
<li>Re-attach the drive to the VM, same approach as detaching except when under the SATA controller click &apos;Add Storage.&apos; The window that appears should already have your drive image listed.</li>
<li>Start your VM</li>
<li>Log in to your VM and become root.</li>
<li>Resize the physical partition. This part can look scary. As with any storage operation you should have a backup of your data. We&apos;re going to delete the partition the LV lives on and the re-create it starting at the same location on the drive but with a last sector that uses all the space on our new larger drive. This only works because the LVM lives on the last physical partition. In the example below my drive is <code>/dev/sda</code> and the LVM lives on <code>sda3</code>:</li>
</ol>
<pre><code>fdisk /dev/sda

Welcome to fdisk (util-linux 2.37.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

GPT PMBR size mismatch (40959999 != 51199999) will be corrected by write.
The backup GPT table is not on the end of the device. This problem will be corrected by write.
This disk is currently in use - repartitioning is probably a bad idea.
It&apos;s recommended to umount all file systems, and swapoff all swap
partitions on this disk.


Command (m for help): p

Disk /dev/sda: 24.41 GiB, 26214400000 bytes, 51200000 sectors
Disk model: VBOX HARDDISK   
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1934161A-4DAE-4D24-9EAA-A28FC324B93F

Device       Start      End  Sectors  Size Type
/dev/sda1     2048     4095     2048    1M BIOS boot
/dev/sda2     4096  3674111  3670016  1.8G Linux filesystem
/dev/sda3  3674112 40959966 37285855 17.8G Linux filesystem

Command (m for help): d
Partition number (1-3, default 3): 

Partition 3 has been deleted.

Command (m for help): n
Partition number (3-128, default 3): 
First sector (3674112-51199966, default 3674112): 
Last sector, +/-sectors or +/-size{K,M,G,T,P} (3674112-51199966, default 51199966): 

Created a new partition 3 of type &apos;Linux filesystem&apos; and of size 22.7 GiB.
Partition #3 contains a LVM2_member signature.

Do you want to remove the signature? [Y]es/[N]o: N

Command (m for help): w

The partition table has been altered.
Syncing disks.
</code></pre>
<ol start="8">
<li>Reboot your VM</li>
<li>Log back in to your VM and become root</li>
<li>Reized the LVM Physical Volume:</li>
</ol>
<pre><code class="language-bash"># pvresize /dev/sda3
  Physical volume &quot;/dev/sda3&quot; changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
</code></pre>
<ol start="11">
<li>Grow the Logical Volume. My LVM is at <code>/dev/mapper/ubuntu--vg-ubuntu--lv</code>, change if yours is different:</li>
</ol>
<pre><code class="language-bash"># lvextend -L +10G /dev/mapper/ubuntu--vg-ubuntu--lv
  Size of logical volume ubuntu-vg/ubuntu-lv changed from &lt;17.78 GiB (4551 extents) to &lt;19.78 GiB (5063 extents).
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.
</code></pre>
<p>Depending on how much your increased the size of your drive you&apos;ll need to change the <code>+10G</code> parameter. You can always re-run the command with smaller sizes to keep adding a little more space until all extents are consumed.<br>
12. Resize the filesystem. Again, my LVM is at <code>/dev/mapper/ubuntu--vg-ubuntu--lv</code>:</p>
<pre><code class="language-bash"># resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/mapper/ubuntu--vg-ubuntu--lv is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 3
The filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv is now 5940224 (4k) blocks long.
</code></pre>
<p>Enjoy your extra space!</p>
<pre><code class="language-bash"># df -h
Filesystem                         Size  Used Avail Use% Mounted on
tmpfs                              393M  756K  392M   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv   23G   17G  4.5G  79% /
tmpfs                              2.0G     0  2.0G   0% /dev/shm
tmpfs                              5.0M     0  5.0M   0% /run/lock
/dev/sda2                          1.7G  127M  1.5G   8% /boot
tmpfs                              393M  4.0K  393M   1% /run/user/1000
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Testing Syntax Highlighting]]></title><description><![CDATA[<pre><code class="language-bash">echo testing 1 2 3</code></pre>]]></description><link>https://xensoft.com/testing-syntax-highlighting/</link><guid isPermaLink="false">6248cb61952cee0339bb0569</guid><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Sat, 02 Apr 2022 22:17:35 GMT</pubDate><content:encoded><![CDATA[<pre><code class="language-bash">echo testing 1 2 3</code></pre>]]></content:encoded></item><item><title><![CDATA[Coming soon]]></title><description><![CDATA[<p>This is XenSoft, a brand new site by John Westlund that&apos;s just getting started. Things will be up and running here shortly, but you can <a href="#/portal/">subscribe</a> in the meantime if you&apos;d like to stay up to date and receive emails when new content is published!</p>]]></description><link>https://xensoft.com/coming-soon/</link><guid isPermaLink="false">6237baf86e6e8e25ccc7bb8f</guid><category><![CDATA[News]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Sun, 20 Mar 2022 23:38:32 GMT</pubDate><media:content url="https://static.ghost.org/v4.0.0/images/feature-image.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://static.ghost.org/v4.0.0/images/feature-image.jpg" alt="Coming soon"><p>This is XenSoft, a brand new site by John Westlund that&apos;s just getting started. Things will be up and running here shortly, but you can <a href="#/portal/">subscribe</a> in the meantime if you&apos;d like to stay up to date and receive emails when new content is published!</p>]]></content:encoded></item><item><title><![CDATA[Print BASH Array Elements on Separate Lines]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Very easy and usually accomplished with a loop:</p>
<pre><code class="language-bash">$ array=(red green blue)
$ for I in ${array[@]}; do echo $I; done
red
green
blue
</code></pre>
<p>But we can do better!:</p>
<pre><code class="language-bash">$ printf &apos;%s\n&apos; &quot;${array[@]}&quot;
</code></pre>
<p>or:</p>
<pre><code class="language-bash">$ ( IFS=$&apos;\n&apos;; echo &quot;${array[*]}&quot; )
</code></pre>
<p>Note the switch to <code>&quot;</code></p>]]></description><link>https://xensoft.com/print-bash-array-elements-on-separate-lines/</link><guid isPermaLink="false">6237ca6a952cee0339bb046f</guid><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Sat, 17 Dec 2016 04:50:10 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Very easy and usually accomplished with a loop:</p>
<pre><code class="language-bash">$ array=(red green blue)
$ for I in ${array[@]}; do echo $I; done
red
green
blue
</code></pre>
<p>But we can do better!:</p>
<pre><code class="language-bash">$ printf &apos;%s\n&apos; &quot;${array[@]}&quot;
</code></pre>
<p>or:</p>
<pre><code class="language-bash">$ ( IFS=$&apos;\n&apos;; echo &quot;${array[*]}&quot; )
</code></pre>
<p>Note the switch to <code>&quot;${array[*]}&quot;</code> from <code>&quot;${array[@]}&quot;</code> (the &quot;quoting&quot; is important!). Using <code>[@]</code> each element of the array is expanded into a separate quoted argument,  while <code>[*]</code> expands to a single quoted argument of all elements -- with each element separated by the first character of the <code>IFS</code> variable (i.e. newlines in this case).</p>
<p>The above command also runs within a subshell so that <code>IFS</code> is restored after running the command. Also, the reason the value of <code>IFS</code> is a quoted <code>\n</code> starting with a <code>$</code> is so bash expands the control sequence  without dropping any trailing newlines (which command substitution does):</p>
<pre><code class="language-bash"># expand control sequences without modification
$ echo -n $&apos;\n&apos; | od -c
0000000  \n
0000001

# with command substitution, no more \n
$ echo -n $(echo -ne &apos;\n&apos;) | od -c
0000000
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[A Colorful Condensed git log]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Out of the box git commit logs are a bit drab.</p>
<pre><code>commit f93f639563850136a11c4cbc39a119c6905feaf2
Author: John Westlund &lt;email@addr&gt;
Date:   Mon Dec 12 15:49:17 2016 -0800

    broke some stuff

commit 7dc383f214dd9155d78e4542a993607ec07eaa84
Author: Other Dev &lt;email2@addr&gt;
Date:   Mon Dec 12 15:26:16 2016 -0800</code></pre>]]></description><link>https://xensoft.com/a-colorful-condensed-git-log/</link><guid isPermaLink="false">6237ca6a952cee0339bb046e</guid><category><![CDATA[Git]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Fri, 16 Dec 2016 23:33:28 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Out of the box git commit logs are a bit drab.</p>
<pre><code>commit f93f639563850136a11c4cbc39a119c6905feaf2
Author: John Westlund &lt;email@addr&gt;
Date:   Mon Dec 12 15:49:17 2016 -0800

    broke some stuff

commit 7dc383f214dd9155d78e4542a993607ec07eaa84
Author: Other Dev &lt;email2@addr&gt;
Date:   Mon Dec 12 15:26:16 2016 -0800

    fixed some stuff

commit 015ac5ff9b39143c91d5dc136a2c8d578b733e27
Author: Other Dev &lt;email2@addr&gt;
Date:   Mon Dec 12 15:15:23 2016 -0800

    added some stuff
</code></pre>
<p>I find the following a little more useful:</p>
<pre><code class="language-bash">git log --color --graph --pretty=format:&apos;%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&lt;%an&gt;%Creset&apos; --abbrev-commit
</code></pre>
<p><img src="https://xensoft.com/content/images/2016/12/pretty-git-log.PNG" alt="git log" loading="lazy"></p>
<p>Which makes a useful git alias:</p>
<pre><code class="language-bash">git config --global alias.lg &quot;log --color --graph --pretty=format:&apos;%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&lt;%an&gt;%Creset&apos; --abbrev-commit&quot;
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Change a Repository Name in github]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Go to the project in question an open the &quot;<i class="fa fa-cog"></i> Settings&quot; page. Change the <code>Repository name</code> and click on the <code>Rename</code> button. Github<i class="fa fa-github"></i> will present you with a warning dialog. If you&apos;re renaming a repository that multiple people use you&apos;ll want to make sure you&</p>]]></description><link>https://xensoft.com/change-a-repository-name-in-github/</link><guid isPermaLink="false">6237ca6a952cee0339bb046d</guid><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Fri, 28 Oct 2016 19:30:30 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Go to the project in question an open the &quot;<i class="fa fa-cog"></i> Settings&quot; page. Change the <code>Repository name</code> and click on the <code>Rename</code> button. Github<i class="fa fa-github"></i> will present you with a warning dialog. If you&apos;re renaming a repository that multiple people use you&apos;ll want to make sure you&apos;ve given them a heads up.</p>
<p>Next you need to drop and re-add the remote on your local copy. Or remove and re-clone, but this is the git way:</p>
<pre><code class="language-bash">git remote rm origin
git remote add origin git@github.com:&lt;USER&gt;/&lt;REPO&gt;.git
git pull # this will provide an error, fix:
git branch --set-upstream-to=origin/&lt;BRANCH&gt; &lt;BRANCH&gt;
git pull
</code></pre>
<p>Swap in your details for <code>&lt;USER&gt;</code>, <code>&lt;REPO&gt;</code> and <code>&lt;BRANCH&gt;</code> and you should be good to go!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Redirect or Pipe Output from One Command to Many]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>There are a few possible solutions that range from pretty straight forward to a little tricky.</p>
<h2 id="processsubstitution">Process Substitution</h2>
<p>If you know you&apos;ll always be running under a shell that supports <a href="https://xensoft.com/use-redirection-instead-of-temp-files/">process substitution</a>(<code>bash</code>, <code>zsh</code>, <code>ksh93</code>) multiplexing a command&apos;s output is pretty easy using <code>tee</code>. <code>tee</code> supports</p>]]></description><link>https://xensoft.com/redirect-or-pipe-output-from-one-command-to-many/</link><guid isPermaLink="false">6237ca6a952cee0339bb046b</guid><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Fri, 28 Oct 2016 19:28:23 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>There are a few possible solutions that range from pretty straight forward to a little tricky.</p>
<h2 id="processsubstitution">Process Substitution</h2>
<p>If you know you&apos;ll always be running under a shell that supports <a href="https://xensoft.com/use-redirection-instead-of-temp-files/">process substitution</a>(<code>bash</code>, <code>zsh</code>, <code>ksh93</code>) multiplexing a command&apos;s output is pretty easy using <code>tee</code>. <code>tee</code> supports outputting to multiple &quot;files&quot; and with process redirection those &quot;files&quot; can be other commands.</p>
<pre><code># Output to two other commands, and STDOUT
tee &gt;(commandA) &gt;(commandB)
# Output to three commands, all captured and redirected to commandC
tee &gt;(commandA) &gt;(commandB) | commandC
</code></pre>
<p>Note in the second example that <code>commandC</code> is going to see the output from whatever output <code>tee</code> (i.e. whatever output was piped to <code>tee</code>), <code>commandA</code> and <code>commandB</code> each produced. So, if <code>grep</code> is your <code>commandC</code> you&apos;ll search the output from all three proceeding commands.</p>
<h2 id="filedescriptors">File Descriptors</h2>
<p>If your shell uses <code>/dev</code> file descriptors (i.e. POSIX, e.g. <code>/dev/3</code>).</p>
<pre><code>{ { { tee /dev/fd3 /dev/fd4 | commandFD1 &gt;&amp;5; }
    3&gt;&amp;1 | commandFD3 &gt;&amp;5; }
  4&gt;&amp;1 | commandFD4 &gt;&amp;5;
} &gt; 5&gt;&amp;1
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Add syntax highlighting when pasting code into Outlook 2013]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Full credit goes to <a href="http://www.avbrand.com/blog/v/101199/Adding_a_%27Paste_Code%27_feature_to_Outlook_20102007/">avbrand.com</a> this technique. I&apos;ve made some minor tweaks so it will work if you system is configured with a proxy. Remember you&apos;re using a web service (<a href="https://tohtml.com">https://tohtml.com</a>) to perform the highlighting -- so if the code is <em>really</em> sensitive</p>]]></description><link>https://xensoft.com/add-syntax-highlighting-when-pasting-code-into-outlook-2013/</link><guid isPermaLink="false">6237ca6a952cee0339bb046a</guid><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Mon, 27 Jun 2016 01:15:29 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Full credit goes to <a href="http://www.avbrand.com/blog/v/101199/Adding_a_%27Paste_Code%27_feature_to_Outlook_20102007/">avbrand.com</a> this technique. I&apos;ve made some minor tweaks so it will work if you system is configured with a proxy. Remember you&apos;re using a web service (<a href="https://tohtml.com">https://tohtml.com</a>) to perform the highlighting -- so if the code is <em>really</em> sensitive this may not be for you.</p>
<ol>
<li>Enable Macros</li>
</ol>
<ul>
<li>Click &apos;File&apos;, followed by&apos;Options&apos;</li>
<li>Find &apos;Trust Center&apos;, then &apos;Trust Center Settings&apos;</li>
<li>Select the &apos;Macro Settings&apos; tab</li>
<li>Select &apos;Enable all macros&apos;, and click OK.
<ul>
<li>Again, this is not ideal, I&apos;ll try and follow up with how to self sign your macro</li>
</ul>
</li>
</ul>
<ol>
<li>Enable Developer Mode</li>
</ol>
<ul>
<li>Right-click the Ribbon and select &apos;Customize the Ribbon&apos;</li>
<li>In the list on the right side, underneath Main Tabs, there should be checkbox labeled Developer. Check box if not already checked.</li>
<li>Click OK to close the window.</li>
</ul>
<ol>
<li>Open Visual Basic editor</li>
</ol>
<ul>
<li>Click the &apos;Developer&apos; tab. To the far right of File</li>
<li>Click the &apos;Visual Basic&apos; button</li>
</ul>
<ol>
<li>Add reference to necessary libraries</li>
</ol>
<ul>
<li>Click the &apos;Tools&apos; menu, then &apos;References&apos;</li>
<li>Click &apos;Browse&apos;, then type &apos;FM20.DLL&apos; and press OK
<ul>
<li>This is the Microsoft Forms 2.0 Library</li>
</ul>
</li>
<li>Click OK</li>
</ul>
<ol>
<li>Time to code</li>
</ol>
<ul>
<li>Expand the Project pane on the left and double click &apos;ThisOutlookSession&apos;</li>
<li>A blank code window should appear, if not follow the directions on where to paste the contents below.</li>
<li>Begin by pasting this code at the top of the file:</li>
</ul>
<pre><code class="language-basic">Option Explicit
 
Private Declare Function CloseClipboard Lib &quot;user32&quot; () As Long
Private Declare Function OpenClipboard Lib &quot;user32&quot; (ByVal hwnd As Long) As Long
Private Declare Function GlobalAlloc Lib &quot;kernel32&quot; (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function SetClipboardData Lib &quot;user32&quot; (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function EmptyClipboard Lib &quot;user32&quot; () As Long
Private Declare Function RegisterClipboardFormat Lib &quot;user32&quot; Alias &quot;RegisterClipboardFormatA&quot; (ByVal lpString As String) As Long
Private Declare Function GlobalLock Lib &quot;kernel32&quot; (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib &quot;kernel32&quot; (ByVal hMem As Long) As Long
Private Declare Sub CopyMemory Lib &quot;kernel32&quot; Alias &quot;RtlMoveMemory&quot; (pDest As Any, pSource As Any, ByVal cbLength As Long)
 
Private m_cfHTMLClipFormat As Long
 
Private Const m_sDescription = _
                  &quot;Version:1.0&quot; &amp; vbCrLf &amp; _
                  &quot;StartHTML:aaaaaaaaaa&quot; &amp; vbCrLf &amp; _
                  &quot;EndHTML:bbbbbbbbbb&quot; &amp; vbCrLf &amp; _
                  &quot;StartFragment:cccccccccc&quot; &amp; vbCrLf &amp; _
                  &quot;EndFragment:dddddddddd&quot; &amp; vbCrLf
</code></pre>
<p>Now paste this at the bottom:</p>
<pre><code class="language-basic">Public Sub Pastec()
  PasteCode &quot;c&quot;
End Sub

Public Sub Pastecpp()
  PasteCode &quot;cpp&quot;
End Sub

Public Sub Pasteperl()
  PasteCode &quot;perl&quot;
End Sub

Public Sub Pastepython()
  PasteCode &quot;python&quot;
End Sub

Public Sub Pastehtml()
  PasteCode &quot;html&quot;
End Sub

Public Sub Pastexml()
  PasteCode &quot;xml&quot;
End Sub

Public Sub Pastemysql()
  PasteCode &quot;mysql&quot;
End Sub

Public Sub Pasteshell()
  PasteCode &quot;shell&quot;
End Sub

Public Sub Pastemakefile()
  PasteCode &quot;makefile&quot;
End Sub

Public Sub PasteTeX()
  PasteCode &quot;TeX&quot;
End Sub
 
Private Sub PasteCode(mLanguage As String)
    &apos; Paste code into the message window.
    Dim req
    Dim URL
    Dim f
    Dim r As String
    Dim e, e2
    Dim origT As String
    
    Debug.Print &quot;Starting Paste Code&quot;
    
    URL = &quot;https://tohtml.com/&quot; &amp; mLanguage &amp; &quot;/&quot;
    
    &apos; Retrieve text from the clipboard
    Dim fm As MSForms.DataObject
    Set fm = New MSForms.DataObject
    fm.GetFromClipboard
    r = fm.GetText(1) &apos; Text
    origT = r
    
    If r &lt;&gt; &quot;&quot; Then
        &apos; Get the code colorized by tohtml.com
        f = &quot;code_src=&quot; &amp; Escape(r)
        f = f &amp; &quot;&amp;Submit=Highlight&quot;
        f = f &amp; &quot;&amp;style=hs&quot;
        f = f &amp; &quot;&amp;type=&quot; &amp; Escape(mLanguage)

        Dim HttpReq As Object
        Set HttpReq = CreateObject(&quot;MSXML2.XMLHTTP&quot;)
        With HttpReq
         .Open &quot;POST&quot;, URL, False
         .setRequestHeader &quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;
         .Send (f)
         r = .responseText
        End With

        &apos; Extract the response
        e = InStr(1, r, &quot;&lt;textarea&quot;, vbTextCompare)
        e = InStr(e + 1, r, &quot;&gt;&quot;, vbTextCompare)
        e2 = InStr(e + 1, r, &quot;&lt;/textarea&gt;&quot;, vbTextCompare)
        
        If e &gt; 0 And e2 &gt; e Then
            r = Mid(r, e + 1, e2 - e - 1)

            &apos; Fix the HTML code
            r = Replace(r, &quot;&amp;gt;&quot;, &quot;&gt;&quot;)
            r = Replace(r, &quot;&amp;lt;&quot;, &quot;&lt;&quot;)
            r = Replace(r, &quot;&amp;apos;&quot;, &quot;&apos;&quot;)
            r = Replace(r, &quot;&amp;quot;&quot;, &quot;&quot;&quot;&quot;)
            r = Replace(r, &quot;&amp;amp;&quot;, &quot;&amp;&quot;)
            
            r = Replace(r, &quot;#ffffff&quot;, &quot;#f6f8ff&quot;, 1, 1, vbTextCompare)
            
            PutHTMLClipboard r, origT
            &apos; Paste into current message
            On Error GoTo errHandler
            If TypeName(ActiveWindow) = &quot;Inspector&quot; Then
               If ActiveInspector.IsWordMail And ActiveInspector.EditorType = olEditorWord Then
                    ActiveInspector.WordEditor.Application.Selection.Paste
               End If
            End If
        End If
    End If
    
    Debug.Print &quot;Paste Code Complete&quot;
errHandler:  
End Sub
 
Private Function RegisterCF() As Long
   &apos;Register the HTML clipboard format
   If (m_cfHTMLClipFormat = 0) Then
      m_cfHTMLClipFormat = RegisterClipboardFormat(&quot;HTML Format&quot;)
   End If
   RegisterCF = m_cfHTMLClipFormat  
End Function
 
Private Sub PutHTMLClipboard(sHtmlFragment As String, textVersion As String, Optional sContextStart As String = &quot;&lt;HTML&gt;&lt;BODY&gt;&quot;, Optional sContextEnd As String = &quot;&lt;/BODY&gt;&lt;/HTML&gt;&quot;)
   
   Dim sData As String
   
   If RegisterCF = 0 Then Exit Sub &apos; If we can&apos;t register the clipboard handle, then cancel.
   
   &apos;Add the starting and ending tags for the HTML fragment
   sContextStart = sContextStart &amp; &quot;&lt;!--StartFragment --&gt;&quot;
   sContextEnd = &quot;&lt;!--EndFragment --&gt;&quot; &amp; sContextEnd
   
   &apos;Build the HTML given the description, the fragment and the context. And, replace the offset place holders in the description with values for the offsets of StartHMTL, EndHTML, StartFragment and EndFragment.
   sData = m_sDescription &amp; sContextStart &amp; sHtmlFragment &amp; sContextEnd
   sData = Replace(sData, &quot;aaaaaaaaaa&quot;, Format(Len(m_sDescription), &quot;0000000000&quot;))
   sData = Replace(sData, &quot;bbbbbbbbbb&quot;, Format(Len(sData), &quot;0000000000&quot;))
   sData = Replace(sData, &quot;cccccccccc&quot;, Format(Len(m_sDescription &amp; sContextStart), &quot;0000000000&quot;))
   sData = Replace(sData, &quot;dddddddddd&quot;, Format(Len(m_sDescription &amp; sContextStart &amp; sHtmlFragment), &quot;0000000000&quot;))
 
   textVersion = textVersion &amp; Chr(0)
    
   &apos;Add the HTML code to the clipboard
   If CBool(OpenClipboard(0)) Then
   
      Dim hMemHandle As Long, lpData As Long
        If sHtmlFragment &lt;&gt; &quot;&quot; Then
            hMemHandle = GlobalAlloc(0, Len(sData) + 10)
            
            If CBool(hMemHandle) Then
                     
               lpData = GlobalLock(hMemHandle)
               If lpData &lt;&gt; 0 Then
                  CopyMemory ByVal lpData, ByVal sData, Len(sData)
                  GlobalUnlock hMemHandle
                  EmptyClipboard
                  SetClipboardData m_cfHTMLClipFormat, hMemHandle
               End If
            End If
        End If
      
      hMemHandle = GlobalAlloc(0, Len(textVersion) + 10)
      
      If CBool(hMemHandle) Then
         lpData = GlobalLock(hMemHandle)
         If lpData &lt;&gt; 0 Then
            CopyMemory ByVal lpData, ByVal textVersion, Len(textVersion)
            GlobalUnlock hMemHandle
            If sHtmlFragment = &quot;&quot; Then EmptyClipboard
            SetClipboardData 1, hMemHandle
         End If
      End If
   
      Call CloseClipboard
   End If
End Sub
 
Private Function fixZeros(inSt)
    &apos; Adds a 0 to the front if needed.
    fixZeros = inSt
    If Len(fixZeros) = 1 Then fixZeros = &quot;0&quot; &amp; fixZeros
End Function

Private Function Escape(inTxt)
    &apos; Escape the text.
    Dim i
    Dim outText
    
    outText = inTxt
    Escape = outText
    
    Escape = Replace(Escape, &quot;%&quot;, &quot;%25&quot;)
    For i = 1 To 255
        If i = 37 Then
            &apos; skip %
        ElseIf i &gt;= 65 And i &lt;= 90 Then
            &apos; A-Z
        ElseIf i &gt;= 97 And i &lt;= 122 Then
            &apos; a-z
        ElseIf i &gt;= 48 And i &lt;= 57 Then
            &apos; 0-9
        Else
            Escape = Replace(Escape, Chr(i), &quot;%&quot; &amp; fixZeros(Hex(i)))
        End If
    Next
End Function
</code></pre>
<p>The first portion of the above defines functions for each language you might want to highlight -- feel free to add more from the list on <a href="http://tohtml.com">http://tohtml.com</a>. Use the values of the entries in the &apos;Type&apos; combo box (i.e. look at the page source).</p>
<p>For example this would add a function for <code>Cobol</code>:</p>
<pre><code class="language-basic">Public Sub PasteCobol()
    PasteCode &quot;cobol&quot;
</code></pre>
<p>To finish up create buttons for the email drafting window:</p>
<ol>
<li>Open an email compose or reply window.
<ul>
<li>I have had mixed results when the e-mail in embedded in the Outlook window -- &quot;Pop-out&quot; the composition window first.</li>
</ul>
</li>
</ol>
<ul>
<li>Right-click the Ribbon and select &apos;Customize the Ribbon&apos;</li>
<li>Click &apos;New Group&apos; in the lower right</li>
<li>Rename it to &apos;Paste Code&apos;</li>
<li>On the Left side change the dropdown from &apos;Popular Commands&apos; to &apos;Macros&apos;</li>
<li>You should now see &apos;Project1.ThisOutlookSession.PasteXXX&apos;, etc.</li>
<li>Select the one&apos;s you want to easily be able to use and click &apos;Add&apos;</li>
<li>Click Rename and clean up the name, e.g. like &apos;Paste C++&apos;</li>
<li>Click OK</li>
<li>Copy some code, and paste it into the email using your new buttons</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[See 'return codes' from Commands Inside a Chain of Pipes (pipeline)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>It can be hard to tell if everything went okay inside a chain of pipes since <code>$?</code> will only report the return code from the final command in the chain.</p>
<p>Using a different variable (<code>$PIPESTATUS</code>) the return codes of all the commands chained together can be found.</p>
<pre><code class="language-bash">#!/bin/bash

# as long</code></pre>]]></description><link>https://xensoft.com/see-return-codes-from-commands-inside-a-chain-of-pipes/</link><guid isPermaLink="false">6237ca6a952cee0339bb0469</guid><category><![CDATA[Bash]]></category><category><![CDATA[Scripting]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Tue, 14 Jun 2016 02:36:01 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>It can be hard to tell if everything went okay inside a chain of pipes since <code>$?</code> will only report the return code from the final command in the chain.</p>
<p>Using a different variable (<code>$PIPESTATUS</code>) the return codes of all the commands chained together can be found.</p>
<pre><code class="language-bash">#!/bin/bash

# as long as the last command in the pipe chain exits 0, RC will be set to 0
(exit 1) | (exit 2) | (exit 3) | true
echo &quot;Pipe chain RC               : $?&quot;

echo -e &quot;\n# Try again, using PIPESTATUS afterwards to see all RCs&quot;
(exit 1) | (exit 2) | (exit 3) | true
# array of exit codes from the pipe chain
echo &quot;Full PIPESTATUS array       : ${PIPESTATUS[@]}&quot;

# uh oh, running a command has reset the array
echo &quot;Post \&quot;echo\&quot; PIPESTATUS array: ${PIPESTATUS[@]}&quot;

echo -e &quot;\n# Try again, saving the PIPESTATUS&quot;
(exit 1) | (exit 2) | (exit 3) | true
SAVESTATUS=(&quot;${PIPESTATUS[@]}&quot;) # make a copy of the array

# uh oh, running a command has reset the array
echo &quot;Post \&quot;SAVE\&quot; PIPESTATUS array: ${PIPESTATUS[@]}&quot;

# but the copy is safe
echo &quot;Full SAVESTATUS array       : ${SAVESTATUS[@]}&quot;
echo &quot;Post \&quot;echo\&quot; SAVESTATUS array: ${SAVESTATUS[@]}&quot;

set -o pipefail
echo -e &quot;\n# Try again, turn on the BASH option for pipefail&quot;
(exit 1) | (exit 2) | (exit 3) | true | echo &apos;Full pipeline still runs&apos;
echo &quot;Pipe chain RC               : $?&quot;
</code></pre>
<p>Produces the following output:</p>
<pre><code>Pipe chain RC               : 0

# Try again, using PIPESTATUS afterwards to see all RCs
Full PIPESTATUS array       : 1 2 3 0
Post &quot;echo&quot; PIPESTATUS array: 0

# Try again, saving the PIPESTATUS
Post &quot;SAVE&quot; PIPESTATUS array: 0
Full SAVESTATUS array       : 1 2 3 0
Post &quot;echo&quot; SAVESTATUS array: 1 2 3 0

# Try again, turn on the BASH option for pipefail
Full pipeline still runs
Pipe chain RC               : 3
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Track BASH script command failures or abort after N failures]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Using the <code>trap</code> built-in signals received by a scripts (e.g. <code>SIGINT</code>). Using this functionality a script can also take actions based on errors. This can allow some more nuanced handling as opposed to <code>set -e</code>.</p>
<pre><code class="language-bash">#!/bin/bash

ErrorThreshold=5
Cumulative_RC=0
ErrorCount=0

TrackErrorTrap() {
    ((Cumulative_RC += $?))
    ((ErrorCount++))
    if</code></pre>]]></description><link>https://xensoft.com/track-bash-script-command-failures-or-abort-after-n-failures/</link><guid isPermaLink="false">6237ca6a952cee0339bb0468</guid><category><![CDATA[Bash]]></category><category><![CDATA[Scripting]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Tue, 14 Jun 2016 00:00:06 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Using the <code>trap</code> built-in signals received by a scripts (e.g. <code>SIGINT</code>). Using this functionality a script can also take actions based on errors. This can allow some more nuanced handling as opposed to <code>set -e</code>.</p>
<pre><code class="language-bash">#!/bin/bash

ErrorThreshold=5
Cumulative_RC=0
ErrorCount=0

TrackErrorTrap() {
    ((Cumulative_RC += $?))
    ((ErrorCount++))
    if [[ $ErrorCount -gt $ErrorThreshold ]]; then
        echo -e &quot;\n\n###############################&quot;
        echo &quot;Too many errors&quot;
        echo &quot;Count   : $ErrorCount&quot;
	echo &quot;Total RC: $Cumulative_RC&quot;
	exit $Cumulative_RC # Don&apos;t need to exit, can just take some action
    fi
}

trap TrackErrorTrap ERR

for I in {1..10}; do
    echo -n &quot;Error #: $I &quot;
    false                 # when ErrorThreshold is exceeded, the trap will abort
    echo &quot;[COMPLETE]&quot;
done

# script never makes it this far
echo &quot;The rest of the script&quot;
</code></pre>
<p>Running the above results in:</p>
<pre><code>Error #: 1 [COMPLETE]
Error #: 2 [COMPLETE]
Error #: 3 [COMPLETE]
Error #: 4 [COMPLETE]
Error #: 5 [COMPLETE]
Error #: 6 

###############################
Too many errors
Count   : 6
Total RC: 6
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Use sed to Insert Text Every 'n' Lines/Characters]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>There are a lot of overly complicated ways to insert a line after every n<sup>th</sup> line, but the simplest way I find is the following:</p>
<pre><code class="language-bash">sed &apos;0~3 s/$/\nMy Text/g&apos; &lt; input.file
</code></pre>
<p>In a file with six lines you get something like the following:</p>]]></description><link>https://xensoft.com/use-sed-to-insert-text-every-n-lines-characters/</link><guid isPermaLink="false">6237ca6a952cee0339bb0462</guid><category><![CDATA[CLI]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Sun, 22 Nov 2015 21:11:20 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>There are a lot of overly complicated ways to insert a line after every n<sup>th</sup> line, but the simplest way I find is the following:</p>
<pre><code class="language-bash">sed &apos;0~3 s/$/\nMy Text/g&apos; &lt; input.file
</code></pre>
<p>In a file with six lines you get something like the following:</p>
<pre><code class="language-none">Line 1
Line 2
Line 3
My Text
Line 4
Line 5
Line 6
My Text
</code></pre>
<p>Just swap the second half of <code>0~3</code> with the number of lines after which you want to insert to adjust where you insert your text, e.g. <code>0~30</code> will insert every 30<sup>th</sup> line.</p>
<p>The first digit of the <code>0~3</code> specifies the first line the insertion should happen (with <code>0</code> not prepending to the beginning of the file):</p>
<pre><code class="language-bash">sed &apos;2~3 s/$/\nMy Text/g&apos; &lt; input.file 
Line 1
Line 2
My Text
Line 3
Line 4
Line 5
My Text
Line 6
</code></pre>
<p>To insert something every n<sup>th</sup> character the syntax is a bit different:</p>
<pre><code class="language-bash">sed &apos;s/.\{2\}/&amp;#/g&apos;
</code></pre>
<p>Will insert a <code>#</code> every 2 characters:</p>
<pre><code class="language-none">Li#ne# 1#
Li#ne# 2#
Li#ne# 3#
Li#ne# 4#
Li#ne# 5#
Li#ne# 6#
</code></pre>
<p>Swap out the 2 for the desired number of characters.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Simple Free-Tier AWS EC2 Instance Setup]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This is the first of a few articles detailing how to host multiple <code>Node.js</code> or <code>PHP</code> websites on a single EC2 instance.</p>
<ol>
<li>Log in to AWS, and click on EC2</li>
<li>Click on <code>Launch Instance</code> under Create Instance <img src="https://xensoft.com/content/images/2015/11/1-EC2dash.PNG" alt="EC2 Dashboard" loading="lazy"></li>
<li>Select the underlying OS you&apos;d like to use. I&apos;</li></ol>]]></description><link>https://xensoft.com/simple-free-tier-aws-ec2-instance-setup/</link><guid isPermaLink="false">6237ca6a952cee0339bb041f</guid><category><![CDATA[AWS]]></category><category><![CDATA[Ghost]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Wed, 11 Nov 2015 07:41:25 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>This is the first of a few articles detailing how to host multiple <code>Node.js</code> or <code>PHP</code> websites on a single EC2 instance.</p>
<ol>
<li>Log in to AWS, and click on EC2</li>
<li>Click on <code>Launch Instance</code> under Create Instance <img src="https://xensoft.com/content/images/2015/11/1-EC2dash.PNG" alt="EC2 Dashboard" loading="lazy"></li>
<li>Select the underlying OS you&apos;d like to use. I&apos;ve chosen <em>Amazon Linux</em> because it&apos;s essentially <code>RHEL</code> but cheaper and qualifies for the free-tier. There are a lot of other free-tier base OS options, but Amazon is the cheapest after the first year ends. <img src="https://xensoft.com/content/images/2015/11/2-AmazonAMI.PNG" alt="AMI image selection" loading="lazy"></li>
<li>Choose an instance type. The free-tier gives you one option, <code>t2.micro</code>, 1 vCPU and 1 gig of RAM. Not much but sufficient for a few <code>Node.js</code> instances assuming they&apos;re not getting slammed. <img src="https://xensoft.com/content/images/2015/11/3-InstanceType.PNG" alt loading="lazy"> Just remember that for a 64-bit system a <code>Node.js</code> application defaults to a max memory usage of 1 gig. In practice you&apos;ll probably see ~115 megs for something like <a href="http://ghost.org">Ghost</a>.</li>
<li>Now you can select <code>Review and Launch</code> but my recomentation is to continue with <code>Next: Configure Instance Details</code>. Here I would turn on <strong>Enable termination protection</strong> which prevents your instance from being erased unless you <em>really</em> want it to be. <img src="https://xensoft.com/content/images/2015/11/4-InstanceDetails.PNG" alt="Instance details" loading="lazy"></li>
<li>Continue on with <code>Next: Add Storage</code>. The defaults here are fine, but you can get up to 30 GiB on the free-tier, so why not bump that up. <img src="https://xensoft.com/content/images/2015/11/5-Storage.PNG" alt="Storage setup" loading="lazy"> I would also de-select <strong>Delete on Termination</strong> just to provide more hoops before doing something irreversible.</li>
<li>Click <code>Next: Tag Instance</code>. I don&apos;t personally tag my instances, but feel free to do so.</li>
<li>Proceed by clicking <code>Next: Configure Security Group</code>. Here you&apos;ll need to open up the ports to any services you want externally available. <code>SSH</code> is there by default, but as a web-server make sure that <code>HTTP</code> and <code>HTTPS</code> are open. This acts as your instances &apos;Firewall&apos;. <img src="https://xensoft.com/content/images/2015/11/6-SecurityGroup.PNG" alt="Add additional open ports" loading="lazy"></li>
<li>Now select <code>Review and Launch</code>. Double check everything, and if it&apos;s how you expect it hit <code>Launch</code>.</li>
<li>Time to generate a key pair to access your instance via <code>ssh</code>. <img src="https://xensoft.com/content/images/2015/11/7-GenerateKey.PNG" alt="Generate key pair" loading="lazy"> Pick a name, and then &apos;Download Key Pair&apos;. Time to launch the instance.</li>
<li>The instance will have a temporary IP that will only belong to the instance as long as it&apos;s running. As a more persistent solution go back to the dashboard and click on &apos;Elastic IP&apos; and then <code>Allocate New Address</code>. Confirm the allocation, and then associate the new Elastic IP to the instance. <img src="https://xensoft.com/content/images/2015/11/8-ElasticIP.PNG" alt="Associate Address" loading="lazy"> Click inside the <strong>Instance</strong> input field, and the instance&apos;s ID should pop up.</li>
<li>Time to setup <code>~/.ssh/config</code>. Move the <code>.pem</code> key pair file downloaded earlier into <code>~/.ssh</code> and then add the following to your <code>~/.ssh/config</code>, substituting the new Elastic IP and key pair name:</li>
</ol>
<pre><code>Host aws
        HostName &lt;Elastic IP&gt;
        User ec2-user
        IdentityFile ~/.ssh/&lt;newkey&gt;.pem
</code></pre>
<p>Now things are all set up to log into the instance and continue the configuration of services: <code>ssh aws</code></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Convert an AWS instance-store AMI to an EBS backed AMI]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Borrowed this from a site I had to pull up via Google&apos;s cache with some additions.</p>
<p>I recently needed to convert an AWS instance-store AMI to an EBS backed AMI. Here&#x2019;s the steps I took in order to fix that. It&#x2019;s a ext3 file</p>]]></description><link>https://xensoft.com/convert-an-aws-instance-store-ami-to-an-ebs-backed-ami/</link><guid isPermaLink="false">6237ca6a952cee0339bb041e</guid><category><![CDATA[AWS]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Tue, 10 Nov 2015 07:39:09 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Borrowed this from a site I had to pull up via Google&apos;s cache with some additions.</p>
<p>I recently needed to convert an AWS instance-store AMI to an EBS backed AMI. Here&#x2019;s the steps I took in order to fix that. It&#x2019;s a ext3 file system in this example, but it should work fine with an ext4 as well.</p>
<ol>
<li>
<p>Launch your instance-store AMI</p>
</li>
<li>
<p>Create a new EBS in the same availability zone</p>
</li>
<li>
<p>Attach the EBS to the instance-store instance on <code>/dev/sdh</code></p>
</li>
<li>
<p>Create the file system<br>
If you&apos;re trying to decide which filesystem to use:<br>
<a href="http://www.phoronix.com/scan.php?page=article&amp;item=ext4_btrfs_nilfs2&amp;num=1">Phoronix Comparison of FileSystems</a>. tl;dr version:</p>
<ul>
<li>NILFS2 has better random read performance</li>
<li>EXT3 has better multi threaded read performance</li>
<li>EXT4 has better overall performance.</li>
</ul>
</li>
</ol>
<pre><code class="language-bash">mkfs.ext3 /dev/sdh
</code></pre>
<ol>
<li>Mount the device</li>
</ol>
<pre><code class="language-bash">mkdir /mnt/ebs
mount /dev/sdh /mnt/ebs
</code></pre>
<ol start="6">
<li>Shut down any running applications or databases that you have and<br>
<code>rsync</code> your system to the EBS volume</li>
</ol>
<pre><code class="language-bash">rsync -avHx / /mnt/ebs
rsync -avHx /dev /mnt/ebs
</code></pre>
<ol start="7">
<li>Label the device</li>
</ol>
<pre><code class="language-bash">tune2fs -L &apos;/&apos; /dev/sdh
</code></pre>
<ol start="8">
<li>Sync and unmount the device</li>
</ol>
<pre><code class="language-bash">sync;sync;sync;sync &amp;&amp; umount /mnt/ebs
</code></pre>
<ol start="9">
<li>In the AWS Console, make a snapshot of the EBS drive</li>
<li>Make a note of the AKI and ARI of the currently running instance (skip this if none are set)</li>
<li>When the snapshot is complete, right click on it and choose &quot;Create Image from Snapshot&quot;</li>
<li>Use the wizard to set an name and description of your new AMI. Also choose the right AKI etc.</li>
<li>You should now be able to start a new instance from the newly created AMI.</li>
</ol>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Check out a _link from OBS]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>If you&apos;re looking to edit the <code>_link</code> file stored in the repository underlying your <code>OBS</code> you can check it out with the <code>--unexpand-link</code> option. Otherwise you&apos;ll end up with the <code>_service</code> file:</p>
<pre><code class="language-bash">osc checkout --unexpand-link &lt;Project&gt; &lt;Package&gt;
# or if you&apos;re</code></pre>]]></description><link>https://xensoft.com/check-out-a-_link-from-obs/</link><guid isPermaLink="false">6237ca6a952cee0339bb041d</guid><category><![CDATA[CLI]]></category><category><![CDATA[OBS]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Sun, 08 Nov 2015 03:55:14 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>If you&apos;re looking to edit the <code>_link</code> file stored in the repository underlying your <code>OBS</code> you can check it out with the <code>--unexpand-link</code> option. Otherwise you&apos;ll end up with the <code>_service</code> file:</p>
<pre><code class="language-bash">osc checkout --unexpand-link &lt;Project&gt; &lt;Package&gt;
# or if you&apos;re already in the project&apos;s directory:
osc checkout --unexpand-link &lt;Package&gt;

</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Always Display Filename with grep]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>The easiest way to accomplish this is if you have a relatively recent GNU version of <code>grep</code>. Then the <code>-H</code> version is available to you:</p>
<pre><code class="language-bash">printf &quot;This\nis\a\ntest&quot; &gt; /tmp/grep.test
grep -H &apos;is&apos; /tmp/grep.test 
/tmp/grep.test:This
/tmp/grep.</code></pre>]]></description><link>https://xensoft.com/always-display-filename-with-grep/</link><guid isPermaLink="false">6237ca6a952cee0339bb041c</guid><category><![CDATA[CLI]]></category><dc:creator><![CDATA[John Westlund]]></dc:creator><pubDate>Sun, 08 Nov 2015 00:28:29 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>The easiest way to accomplish this is if you have a relatively recent GNU version of <code>grep</code>. Then the <code>-H</code> version is available to you:</p>
<pre><code class="language-bash">printf &quot;This\nis\a\ntest&quot; &gt; /tmp/grep.test
grep -H &apos;is&apos; /tmp/grep.test 
/tmp/grep.test:This
/tmp/grep.test:is
</code></pre>
<p>But if the <code>-H</code> isn&apos;t available to you (I&apos;m looking at your SunOS/Solaris) there&apos;s still hope, and it&apos;s nearly as easy:</p>
<pre><code class="language-bash">printf &quot;This\nis\a\ntest&quot; &gt; /tmp/grep.test
grep &apos;is&apos; /dev/null /tmp/grep.test
/tmp/grep.test:This
/tmp/grep.test:is
</code></pre>
<p>By giving <code>grep</code> <code>/dev/null</code> (which it sees as a zero length file) in addition to the file you&apos;d like to search <code>grep</code> sees two files and will report back the filename of the file you&apos;d like to search.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>