<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>bash &amp;mdash; th.oughts</title>
    <link>https://th.oughts.org/tag:bash</link>
    <description>Living the fake American dream, 3 years at a time</description>
    <pubDate>Fri, 17 Apr 2026 04:07:46 +0000</pubDate>
    <image>
      <url>https://i.snap.as/ixKmaGoG.jpg</url>
      <title>bash &amp;mdash; th.oughts</title>
      <link>https://th.oughts.org/tag:bash</link>
    </image>
    <item>
      <title>Getting into tape backups (Part 2)</title>
      <link>https://th.oughts.org/getting-into-tape-backups-part-2?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In Part 1, we had a quick introduction to tapes and tape drives and why you would choose one for your backups. In this part, we talk about actually using tapes to create a backup strategy using simple scripting.&#xA;&#xA;Of course,  there are plenty of readily available tools that might suit your needs. Writing your own does have a few advantages though: first, it keeps it simple, highly customized and second, when things go wrong, you would probably have a better idea of why the damn thing isn&#39;t working!&#xA;&#xA;A look at tape&#39;s workings&#xA;&#xA;If this is your first time dealing with tapes(as it was for me), there&#39;s a few prerequisites. &#xA;&#xA;Tools&#xA;Tape operations are carried out via the mt tool. Data is written with tar.&#xA;Both of these are probably already installed on your system.&#xA;&#xA;Writing data to tapes&#xA;Do you remember the good old days of cassette players ? Tapes are similar. A magnetic head reads and writes data from a magnetic ribbon spooled in an enclosure. With that in mind, there are a few operations that you would do frequently:&#xA;&#xA;  rewind: rewinds(of course!) the tape and points the tape head to the beginning of the magnetic ribbon.&#xA;Example command: mt -f /dev/nst0 rewind&#xA;  &#xA;  forward:  Move forward count files. Every time data is written, a marker is set at the end. Let&#39;s say, you write some data to the beginning of the tape: tar cvf /dev/nst0 backupdir&#xA;Rewind the tape as above. Now, you want to move forward one marker: mt -f /dev/nst0 fsf 1&#xA;&#xA;  erase: That&#39;s a really slow process and could take hours (if not days) for larger tapes. However, you can also do a short erase: mt -f /dev/nst0 erase 0.&#xA;&#xA;Tar and incremental backups&#xA;tar has a handy feature that lets you do incremental backups and the workings are really simple.&#xA;Let&#39;s look at an example:&#xA;&#xA;tar -C /home --listed-incremental=diff.snar -clpMvf /dev/nst0 data&#xA;This is what we call a Level 0 backup. diff.snar is special - it contains a log of all the files that were added to the archive.&#xA;&#xA;Next, lets&#39;s say you add file.txt to folder data and run the above command again. The only file that would be added to the archive is file.txt. Moreover, diff.snar would also be overwritten with the only one entry that was just added to the archive. This would be a Level 1 archive.&#xA;&#xA;Obviously, if you would want to have a record of all the backups, you wouldn&#39;t want to overwrite diff.snar but have rather something like this:&#xA;&#xA;diff0.snar: level0 backup&#xA;diff1.snar: level1 backup&#xA;and so on...&#xA;&#xA;Backup Strategy&#xA;With all this quick preliminary information, we can try a incremental backup strategy as follows:&#xA;&#xA;Maintain two sets of full backup tapes and two sets of incremental backup tapes.&#xA;Create a full backup the start of every cycle: could be a month, bimonthly, quarterly or whatever you prefer.&#xA;Until the beginning of next cycle, perform incremental backups.&#xA;At any point of time, you should always have a backup set that has a full backup of the last cycle as well as incremental backup tape(s) of the last cycle.&#xA;&#xA;Tape utility script illustrates the idea. To perform a full backup, you would run something like:&#xA;&#xA;tapeutility.sh -d /dev/nst0 -F -p /etc/tapeutility/folders.txt where &#34;-F&#34; does a full backup of folders listed in &#34;folders.txt&#34;.&#xA;&#xA;For the next run, to create an incremental backup, you would run:&#xA;tapeutility.sh -d /dev/nst0 -I -p /etc/tapeutility/folders.txt where &#34;-I&#34; does an incremental backup. &#xA;&#xA;Please take a look at the script for how the metadata file is determined for incremental backup and other features available for basic tape maintenance.&#xA;&#xA;Wrap-up&#xA;I presented a simple way to use tapes for backups. Using a combination of full and incremental backups, and maintaining two sets of tapes, we have reliable backup of data that you could combine with a RAID style setup for long term reliable data storage.&#xA;&#xA;#backups #bash #diy&#xA;&#xA;a href=&#34;https://remark.as/p/th.oughts.org/getting-into-tape-backups-part-2&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p>In <a href="https://th.oughts.org/getting-into-tape-backups-part-1">Part 1</a>, we had a quick introduction to tapes and tape drives and why you would choose one for your backups. In this part, we talk about actually using tapes to create a backup strategy using simple scripting.</p>

<p>Of course,  there are plenty of readily available tools that might suit your needs. Writing your own does have a few advantages though: first, it keeps it simple, highly customized and second, when things go wrong, you would probably have a better idea of why the damn thing isn&#39;t working!</p>

<h2 id="a-look-at-tape-s-workings" id="a-look-at-tape-s-workings">A look at tape&#39;s workings</h2>

<p>If this is your first time dealing with tapes(as it was for me), there&#39;s a few prerequisites.</p>

<h3 id="tools" id="tools">Tools</h3>

<p>Tape operations are carried out via the <em>mt</em> tool. Data is written with <em>tar</em>.
Both of these are probably already installed on your system.</p>

<h3 id="writing-data-to-tapes" id="writing-data-to-tapes">Writing data to tapes</h3>

<p>Do you remember the good old days of cassette players ? Tapes are similar. A magnetic head reads and writes data from a magnetic ribbon spooled in an enclosure. With that in mind, there are a few operations that you would do frequently:</p>
<ol><li><p><em>rewind</em>: rewinds(of course!) the tape and points the tape head to the beginning of the magnetic ribbon.
Example command: <em>mt -f /dev/nst0 rewind</em></p></li>

<li><p><em>forward</em>:  Move forward count files. Every time data is written, a marker is set at the end. Let&#39;s say, you write some data to the beginning of the tape: <em>tar cvf /dev/nst0 backupdir</em>
Rewind the tape as above. Now, you want to move forward one marker: <em>mt -f /dev/nst0 fsf 1</em></p></li>

<li><p><em>erase</em>: That&#39;s a really slow process and could take hours (if not days) for larger tapes. However, you can also do a short erase: <em>mt -f /dev/nst0 erase 0</em>.</p></li></ol>

<h3 id="tar-and-incremental-backups" id="tar-and-incremental-backups">Tar and incremental backups</h3>

<p><em>tar</em> has a handy feature that lets you do incremental backups and the workings are really simple.
Let&#39;s look at an example:</p>
<ol><li><p><em>tar -C /home —listed-incremental=diff.snar -clpMvf /dev/nst0 data</em>
This is what we call a <strong>Level 0</strong> backup. <em>diff.snar</em> is special – it contains a log of all the files that were added to the archive.</p></li>

<li><p>Next, lets&#39;s say you add <em>file.txt</em> to folder <em>data</em> and run the above command again. The only file that would be added to the archive is <em>file.txt</em>. Moreover, <em>diff.snar</em> would also be overwritten with the only one entry that was just added to the archive. This would be a <strong>Level 1</strong> archive.</p></li></ol>

<p>Obviously, if you would want to have a record of all the backups, you wouldn&#39;t want to overwrite <em>diff.snar</em> but have rather something like this:</p>
<ul><li><em>diff0.snar: level0 backup</em></li>
<li><em>diff1.snar: level1 backup</em>
and so on...</li></ul>

<h3 id="backup-strategy" id="backup-strategy">Backup Strategy</h3>

<p>With all this quick preliminary information, we can try a incremental backup strategy as follows:</p>
<ol><li>Maintain two sets of full backup tapes and two sets of incremental backup tapes.</li>
<li>Create a full backup the start of every cycle: could be a month, bimonthly, quarterly or whatever you prefer.</li>
<li>Until the beginning of next cycle, perform incremental backups.</li>
<li>At any point of time, you should always have a backup set that has a full backup of the last cycle as well as incremental backup tape(s) of the last cycle.</li></ol>

<p><a href="https://bitbucket.org/bdas/tape-backup/src/master/tapeutility.sh">Tape utility script</a> illustrates the idea. To perform a full backup, you would run something like:</p>

<p><em>tapeutility.sh -d /dev/nst0 -F -p /etc/tapeutility/folders.txt</em> where “-F” does a full backup of folders listed in “folders.txt”.</p>

<p>For the next run, to create an incremental backup, you would run:
<em>tapeutility.sh -d /dev/nst0 -I -p /etc/tapeutility/folders.txt</em> where “-I” does an incremental backup.</p>

<p>Please take a look at the script for how the metadata file is determined for incremental backup and other features available for basic tape maintenance.</p>

<h3 id="wrap-up" id="wrap-up">Wrap-up</h3>

<p>I presented a simple way to use tapes for backups. Using a combination of full and incremental backups, and maintaining two sets of tapes, we have reliable backup of data that you could combine with a RAID style setup for long term reliable data storage.</p>

<p><a href="https://th.oughts.org/tag:backups" class="hashtag"><span>#</span><span class="p-category">backups</span></a> <a href="https://th.oughts.org/tag:bash" class="hashtag"><span>#</span><span class="p-category">bash</span></a> <a href="https://th.oughts.org/tag:diy" class="hashtag"><span>#</span><span class="p-category">diy</span></a></p>

<p><a href="https://remark.as/p/th.oughts.org/getting-into-tape-backups-part-2">Discuss...</a></p>
]]></content:encoded>
      <guid>https://th.oughts.org/getting-into-tape-backups-part-2</guid>
      <pubDate>Wed, 10 Aug 2022 04:37:56 +0000</pubDate>
    </item>
    <item>
      <title>Experiences building a RPi based home security camera</title>
      <link>https://th.oughts.org/experiences-building-a-rpi-based-home-security-camera-3tk0?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[My Dad had a specific set of requirements from a security camera he wanted for our home back in India. When I researched between options, on whether to buy one or to build something, I stumbled upon many builds based on the Raspberry Pi. Most successful builds run Motion on top of a RPi board, or maybe, even Motioneye for a friendlier UI. This post summarizes the issues that I/you are likely to face and what I did about them.&#xA;&#xA;Underwhelming hardware&#xA;I used a RPi 3 B board that has a 1.2 Ghz quadcore ARM processor. For processing a video stream and running the motion detection daemon, it&#39;s not really very capable and you would end up with stuck/unusable frames on your stream. One of the things that makes a huge difference is the incoming stream frame rate and resolution. I got the best results with sliding down the incoming frame rate to as low as 10 on the camera that I am using.&#xA;&#xA;B vs B+&#xA;The B+&#39;s advantage is more on the I/O side and it really doesn&#39;t make much of a difference with processing power when it comes to the video stream. On the other hand, the B is more battery friendly which was a major requirement in my setup owing to the frequent power-cuts associated with Indian summers. Overclocking, too, isn&#39;t worth it if you consider the battery drain (as high as 20% faster) compared to any noticeable performance gain.&#xA;&#xA;Backup power&#xA;As mentioned above, this was an important requirement. I used a 20000 mAH  battery that has passthrough. On the downside, when passthrough triggers, there&#39;s a momentary disconnect in power which restarts the camera and the RPi which is undesirable but the small downtime is acceptable.&#xA;&#xA;Network&#xA;One of the requirements was failover to a backup network but jumping back to the main network once it&#39;s back up. A reverse tunnel to a public IP takes care of ssh and http access and could be easily scripted as well. HTTPS is achieved by setting up a nginx reverse proxy on the public facing system and integrating with letsencrypt.&#xA;&#xA;Motion detection&#xA;False positives is a major challenge and I could get a good compromise with a mix of a few things:&#xA;  Setting up a manual mask. This is easy to do with the motioneye http interface.&#xA;  Using a despeckle filter. Take a look at this article for a nice write up by the author. After experimenting with several combinations, EedDl gave the best results (which also happens to be the recommended starting poin).&#xA;Experimenting with thresholds. I used the threshold\maximum parameter to minimize the maximum pixel change. A script  changes &#xA;the threshold value based on input from a LDR similar to this setup.&#xA;&#xA;Usability&#xA;The system is easy to use/configure with the Motioneye http interface but to make it a little bit more interesting, I used some NFC tags to enable/disable motion detection. This can be easily done with Tasker along with the NFC plugin for it. This script takes care of syncing up the config file with the current state of motion detection.&#xA;&#xA;#thoughts #tech #diy #rpi #bash&#xA;&#xA;a href=&#34;https://remark.as/p/th.oughts.org/experiences-building-a-rpi-based-home-security-camera-3tk0&#34;Discuss.../a]]&gt;</description>
      <content:encoded><![CDATA[<p>My Dad had a specific set of requirements from a security camera he wanted for our home back in India. When I researched between options, on whether to buy one or to build something, I stumbled upon many builds based on the Raspberry Pi. Most successful builds run <a href="https://motion-project.github.io">Motion</a> on top of a RPi board, or maybe, even <a href="https://motion-project.github.io">Motioneye</a> for a friendlier UI. This post summarizes the issues that I/you are likely to face and what I did about them.</p>

<h2 id="underwhelming-hardware" id="underwhelming-hardware">Underwhelming hardware</h2>

<p>I used a RPi 3 B board that has a 1.2 Ghz quadcore ARM processor. For processing a video stream and running the motion detection daemon, it&#39;s not really very capable and you would end up with stuck/unusable frames on your stream. One of the things that makes a huge difference is the incoming stream frame rate and resolution. I got the best results with sliding down the incoming frame rate to as low as 10 on the <a href="https://reolink.com/product/rlc-410/">camera</a> that I am using.</p>

<h2 id="b-vs-b" id="b-vs-b">B vs B+</h2>

<p>The B+&#39;s advantage is more on the I/O side and it really doesn&#39;t make much of a difference with processing power when it comes to the video stream. On the other hand, the B is more battery friendly which was a major requirement in my setup owing to the frequent power-cuts associated with Indian summers. Overclocking, too, isn&#39;t worth it if you consider the battery drain (as high as 20% faster) compared to any noticeable performance gain.</p>

<h2 id="backup-power" id="backup-power">Backup power</h2>

<p>As mentioned above, this was an important requirement. I used a 20000 mAH  <a href="https://www.amazon.com/gp/product/B078S6LH8L/">battery</a> that has passthrough. On the downside, when passthrough triggers, there&#39;s a momentary disconnect in power which restarts the camera and the RPi which is undesirable but the small downtime is acceptable.</p>

<h2 id="network" id="network">Network</h2>

<p>One of the requirements was failover to a backup network but jumping back to the main network once it&#39;s back up. A reverse tunnel to a public IP takes care of ssh and http access and could be easily <a href="https://bitbucket.org/bdas/motioneyescripts/src/master/scripts/wifi_switcher.sh">scripted</a> as well. HTTPS is achieved by setting up a nginx reverse proxy on the public facing system and integrating with letsencrypt.</p>

<h2 id="motion-detection" id="motion-detection">Motion detection</h2>

<p>False positives is a major challenge and I could get a good compromise with a mix of a few things:
  – Setting up a manual mask. This is easy to do with the motioneye http interface.
  – Using a despeckle filter. Take a look at this <a href="http://emit.demon.co.uk/motion/">article</a> for a nice write up by the author. After experimenting with several combinations, EedDl gave the best results (which also happens to be the recommended starting poin).
– Experimenting with thresholds. I used the threshold_maximum parameter to minimize the maximum pixel change. A <a href="https://bitbucket.org/bdas/motioneyescripts/src/master/scripts/select_motion.sh">script</a>  changes
the threshold value based on input from a LDR similar to this <a href="https://pimylifeup.com/raspberry-pi-light-sensor/">setup</a>.</p>

<h2 id="usability" id="usability">Usability</h2>

<p>The system is easy to use/configure with the Motioneye http interface but to make it a little bit more interesting, I used some NFC tags to enable/disable motion detection. This can be easily done with <a href="https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm&amp;hl=en">Tasker</a> along with the NFC plugin for it. This <a href="https://bitbucket.org/bdas/motioneyescripts/src/master/scripts/update_motion_trigger.sh">script</a> takes care of syncing up the config file with the current state of motion detection.</p>

<p><a href="https://th.oughts.org/tag:thoughts" class="hashtag"><span>#</span><span class="p-category">thoughts</span></a> <a href="https://th.oughts.org/tag:tech" class="hashtag"><span>#</span><span class="p-category">tech</span></a> <a href="https://th.oughts.org/tag:diy" class="hashtag"><span>#</span><span class="p-category">diy</span></a> <a href="https://th.oughts.org/tag:rpi" class="hashtag"><span>#</span><span class="p-category">rpi</span></a> <a href="https://th.oughts.org/tag:bash" class="hashtag"><span>#</span><span class="p-category">bash</span></a></p>

<p><a href="https://remark.as/p/th.oughts.org/experiences-building-a-rpi-based-home-security-camera-3tk0">Discuss...</a></p>
]]></content:encoded>
      <guid>https://th.oughts.org/experiences-building-a-rpi-based-home-security-camera-3tk0</guid>
      <pubDate>Wed, 30 Jan 2019 05:51:23 +0000</pubDate>
    </item>
  </channel>
</rss>