<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: gunitinug</title>
    <description>The latest articles on Forem by gunitinug (@gunitinug).</description>
    <link>https://forem.com/gunitinug</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1383739%2Fe05c45e9-6f30-4b5c-a142-dcc3c0c3ab13.jpeg</url>
      <title>Forem: gunitinug</title>
      <link>https://forem.com/gunitinug</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gunitinug"/>
    <language>en</language>
    <item>
      <title>How to play a bunch of lemmings</title>
      <dc:creator>gunitinug</dc:creator>
      <pubDate>Mon, 25 Nov 2024 01:30:17 +0000</pubDate>
      <link>https://forem.com/gunitinug/how-to-a-bunch-of-lemmings-588c</link>
      <guid>https://forem.com/gunitinug/how-to-a-bunch-of-lemmings-588c</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56e3x9jqz9wd0zkuvn1j.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56e3x9jqz9wd0zkuvn1j.jpg" alt="cute lemmings" width="293" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've download a bunch of lemmings games for MS-DOS from an abandonware site (so there were all abandonwares). Since there were like six or seven different zip files (each different lemmings game), I used this script to unzip them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=()&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;Lemmings&lt;span class="k"&gt;*&lt;/span&gt;.zip&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c"&gt;# If the item is a file, add it to the array&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;files+&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;fi
done

for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c"&gt;#echo "make directory ${file%.zip}"&lt;/span&gt;

  &lt;span class="c"&gt;# unzip into directory where directory name is the filename with extension&lt;/span&gt;
  &lt;span class="c"&gt;# removed.&lt;/span&gt;
  &lt;span class="nb"&gt;echo &lt;/span&gt;unzipping &lt;span class="s2"&gt;"/my-downloads/&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; to &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/my-dos/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;%.zip&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;...
  unzip &lt;span class="s2"&gt;"/my-downloads/&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/my-dos/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;%.zip&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, each zip file was unzipped to a directory with same name as zip file's file name minus its .zip extension.&lt;/p&gt;

&lt;p&gt;Since I have unzipped all files, now I needed a way to choose and execute each game. I came up with a way to list the executables (including .exe and .bat files) and choose the game to execute by line number.&lt;/p&gt;

&lt;p&gt;I declared an associative array &lt;code&gt;execs_dict&lt;/code&gt; and populated it with the names of executables as keys and their path as values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;declare&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; execs_dict

&lt;span class="k"&gt;for &lt;/span&gt;exe &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"L3D.EXE"&lt;/span&gt; &lt;span class="s2"&gt;"VGALEMMI.EXE"&lt;/span&gt; &lt;span class="s2"&gt;"l2p1.exe"&lt;/span&gt; &lt;span class="s2"&gt;"l2p2.exe"&lt;/span&gt; &lt;span class="s2"&gt;"vgalemmi.exe"&lt;/span&gt; &lt;span class="s2"&gt;"VGALEMM2.EXE"&lt;/span&gt; &lt;span class="s2"&gt;"L3F.EXE"&lt;/span&gt; &lt;span class="s2"&gt;"VGAL.EXE"&lt;/span&gt; &lt;span class="s2"&gt;"lemmings.bat"&lt;/span&gt; &lt;span class="s2"&gt;"L3.BAT"&lt;/span&gt; &lt;span class="s2"&gt;"VGALEMMI.BAT"&lt;/span&gt; &lt;span class="s2"&gt;"Lemmings.bat"&lt;/span&gt; &lt;span class="s2"&gt;"LEMMINGSH.B&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
AT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &lt;/span&gt;&lt;span class="nb"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;find ~/my-dos &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="nv"&gt;$exe&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'\/'&lt;/span&gt; &lt;span class="s1"&gt;'\\'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nv"&gt;c_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;/\\home\\logan\\my-dos\\/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        execs_dict[&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$exe&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;]=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$c_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "LSD.EXE", "VGALEMMI.EXE",... are the game executables across different lemmings games I've unzipped.&lt;/p&gt;

&lt;p&gt;First, I've changed all slashes in the path to backslashes (to be compatiable in dos). Since the paths are to be used inside dosbox, I've removed the leading &lt;code&gt;/home/logan/mydos/&lt;/code&gt;. The resulting string represents the path to the different lemmings executables including the path and executable file.&lt;/p&gt;

&lt;p&gt;Now to implement a way to list all executables and to choose one of them using the line number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initialize counter for line number                                                                                                                                            &lt;/span&gt;
&lt;span class="nv"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1

&lt;span class="c"&gt;# Print the list of keys with line numbers                                                                                                                                      &lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Lemmings...:"&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;key &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;!execs_dict[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$counter&lt;/span&gt;&lt;span class="s2"&gt;) &lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="o"&gt;((&lt;/span&gt;counter++&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# Ask the user to choose a line number                                                                                                                                          &lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"Enter the number: "&lt;/span&gt;
&lt;span class="nb"&gt;read &lt;/span&gt;choice

&lt;span class="c"&gt;# Get the key corresponding to the chosen number                                                                                                                                &lt;/span&gt;
&lt;span class="nv"&gt;chosen_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;!execs_dict[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;&lt;span class="nv"&gt;$choice&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;chosen_key&lt;/code&gt; is the key of &lt;code&gt;execs_dict&lt;/code&gt; we've populated earlier. It will be used to execute the lemmings game later. So we've printed all lemmings executables (.exe and .bat files) one on each line. Then we chose the game to execute using the line number. Then, we figured out the key in &lt;code&gt;execs_dict&lt;/code&gt; which is the executable that we will run.&lt;/p&gt;

&lt;p&gt;But there's a problem: when I run dosbox on linux, it will shorten any file names that are too long. It follows the so-called 8.3 convention. It means the part before the dot, the max length is eight characters. After the dot, the max is three characters. Before the dot, any name longer than eight characters long will be transformed: first six characters plus ~ and then a number (eg. ~1 or ~2).&lt;/p&gt;

&lt;p&gt;I'll give an example. If the file name (could be a file or directory) is LEMMINGSISAWESOME.REALLY, this will be transformed to LEMMIN~1.REA. Do you get this?&lt;/p&gt;

&lt;p&gt;Anyways, in order to run the game I must first shorten both directory and file names from the game executable path. So I wrote these functions &lt;code&gt;shortenDir&lt;/code&gt;, &lt;code&gt;convertDir&lt;/code&gt;, and &lt;code&gt;convertExec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First &lt;code&gt;shortenDir&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# long dir names to dos 8.3 name&lt;/span&gt;
&lt;span class="k"&gt;function &lt;/span&gt;shortenDir&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s1"&gt;'\.'&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="c"&gt;# get f and e where the filename comprised of f.e&lt;/span&gt;
        &lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nv"&gt;e&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt; &lt;span class="nt"&gt;-f2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="c"&gt;#echo f: "$f"&lt;/span&gt;
        &lt;span class="c"&gt;#echo e: "$e"&lt;/span&gt;

        &lt;span class="c"&gt;# get length of f and e&lt;/span&gt;
        &lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
        &lt;span class="nv"&gt;m&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;

        &lt;span class="c"&gt;#echo n: "$n"&lt;/span&gt;
        &lt;span class="c"&gt;#echo m: "$m"&lt;/span&gt;

        &lt;span class="c"&gt;# construct new name in the form a.b&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 8 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-c1-6&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;~1"&lt;/span&gt;
        &lt;span class="k"&gt;else
            &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;fi

        if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$m&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 3 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-c1-3&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;else
            &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;fi
        &lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="c"&gt;# convert all lowercase to capitals&lt;/span&gt;
        &lt;span class="nv"&gt;S&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'a-z'&lt;/span&gt; &lt;span class="s1"&gt;'A-Z'&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$S&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 8 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                        &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-c1-6&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;~1"&lt;/span&gt;
        &lt;span class="k"&gt;else
            &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
                &lt;span class="k"&gt;fi
        &lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="c"&gt;# convert all lowercase to capitals&lt;/span&gt;
                &lt;span class="nv"&gt;S&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'a-z'&lt;/span&gt; &lt;span class="s1"&gt;'A-Z'&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$S&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function will receive a single argument that is the long name to be converted according to the 8.3 rule. But we need more than that. We will receive a full path to the executable - something like D1\D2...\exec.bat. So we need to run the shortenDir function on each of D1, D2, ... Dn parts. So I wrote &lt;code&gt;convertDir&lt;/code&gt; function for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# use shortenDir function to convert all directories from a line&lt;/span&gt;
&lt;span class="c"&gt;# and reassemble the line.&lt;/span&gt;
&lt;span class="c"&gt;# We have:&lt;/span&gt;
&lt;span class="c"&gt;# D1\D2\...\exec.bat&lt;/span&gt;
&lt;span class="c"&gt;# and&lt;/span&gt;
&lt;span class="c"&gt;# we want to shorten all D's: D1,D2,...&lt;/span&gt;
&lt;span class="c"&gt;# then reassemble:&lt;/span&gt;
&lt;span class="c"&gt;# S1\S2\...\Sn&lt;/span&gt;
&lt;span class="k"&gt;function &lt;/span&gt;convertDir&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;base_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;%\\*&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;exec_bat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;##*\\&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;# Split the string into components&lt;/span&gt;
    &lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'\\'&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; components &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$base_path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;#echo components: "${components[@]}"&lt;/span&gt;

    &lt;span class="nv"&gt;conv_d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="c"&gt;#converted dir&lt;/span&gt;
    &lt;span class="c"&gt;# Process each component&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;component &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;components&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &lt;/span&gt;conv_d+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;shortenDir &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$component&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        conv_d+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
    &lt;span class="k"&gt;done&lt;/span&gt;

    &lt;span class="c"&gt;# add back the exec.bat at the end&lt;/span&gt;
    &lt;span class="c"&gt;# chose to not add exec.bat at the end.&lt;/span&gt;
    &lt;span class="c"&gt;#conv_d+="$exec_bat"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$conv_d&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For technicality, it's easier to work with if I omit the exec.bat part at the end, so that's what this function will spit out. It takes a line D1\D2...\Dn\exec.bat as the single argument and converts it to S1\S2....\Sn, where Sn denotes a shortend directory name converted from Dn by shortenDir function.&lt;/p&gt;

&lt;p&gt;Next, not only directory but an executable file name is also converted using the 8.3 rule. So we make another function &lt;code&gt;convertExec&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;function &lt;/span&gt;convertExec&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    shortenDir &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we are ready to use these functions to convert a line of the form D1\D2...D2\exec.bat to S1\S2...\Sn and shortened.bat.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$chosen_key&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;chosen_key&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;
    &lt;span class="c"&gt;# Run the chosen executable&lt;/span&gt;
    dosbox &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"mount C /home/logan/my-dos"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"C:"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;convertDir &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;execs_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$chosen_key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;convertExec &lt;span class="nv"&gt;$chosen_key&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-conf&lt;/span&gt; ~/my-dos/lemmings-dosbox.conf

&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Invalid choice or file not found."&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual bash command that is executed is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dosbox &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"mount C /home/logan/my-dos"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"C:"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"cd &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;convertDir &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;execs_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$chosen_key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;convertExec &lt;span class="nv"&gt;$chosen_key&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-conf&lt;/span&gt; ~/my-dos/lemmings-dosbox.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;-c&lt;/code&gt; flag this allows me to run commands that will be run inside dosbox from command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mount C /home/logan/my-dos
C:
cd path\to\lemmings\
game
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, &lt;code&gt;-conf&lt;/code&gt; option allows me to load a conf file named &lt;code&gt;lemmings-dosbox.conf&lt;/code&gt;. I need this to set a screen resolution so the game is displayed in a decent size on my screen. Here's the content of the conf file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[sdl]
windowresolution=1600x1200
output=opengl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's about it! Now I'm happy that I can play some lemmings!!!! Have a blessed day!&lt;/p&gt;

</description>
      <category>bash</category>
      <category>lemmings</category>
    </item>
    <item>
      <title>How big is my upgrade?</title>
      <dc:creator>gunitinug</dc:creator>
      <pubDate>Fri, 05 Apr 2024 10:37:55 +0000</pubDate>
      <link>https://forem.com/gunitinug/how-big-is-my-upgrade-1bgc</link>
      <guid>https://forem.com/gunitinug/how-big-is-my-upgrade-1bgc</guid>
      <description>&lt;p&gt;Say I want to upgrade my Ubuntu box but I want to find out how big the upgrade operation will be.&lt;/p&gt;

&lt;p&gt;First, we have to find out all the packages to be installed. The &lt;code&gt;-s&lt;/code&gt; option means it's simulation (ie. nothing will be installed).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ apt-get -s upgrade | grep -i ^inst | awk '{print $2}' | tr '\n' ' '
base-files libnss-systemd ... xwayland mutter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package names are separated by a space.&lt;/p&gt;

&lt;p&gt;Now I want to query the installed-size using dpkg-query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dpkg-query -s $(apt-get -s upgrade | grep -i ^inst | awk '{print $2}' | tr '\n' ' ') | grep -i "installed-size"
Installed-Size: 392
...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, just get the numbers (eg. 392) and add them all up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dpkg-query -s $(apt-get -s upgrade | grep -i ^inst | awk '{print $2}' | tr '\n' ' ') | grep -i "installed-size" | awk '{print $2}' | awk '{total+=$1} END {print total}'
2649388
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we've got is total space that will be occupied by apt-get's upgrade operation is 2649388 KB.&lt;/p&gt;

&lt;p&gt;Now we've done the hard part. Phew! What's left is to convert 2649388 KB to GB for our convenience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ total=$(dpkg-query -s $(apt-get -s upgrade | grep -i ^inst | awk '{print $2}' | tr '\n' ' ') | grep -i "installed-size" | awk '{print $2}' | awk '{total+=$1} END {print total}'); bc &amp;lt;&amp;lt;&amp;lt; "scale=5; $total / 1024 / 1024"
2.52665
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To finish, just append GB at the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ total=$(dpkg-query -s $(apt-get -s upgrade | grep -i ^inst | awk '{print $2}' | tr '\n' ' ') | grep -i "installed-size" | awk '{print $2}' | awk '{total+=$1} END {print total}'); bc &amp;lt;&amp;lt;&amp;lt; "scale=5; $total / 1024 / 1024" | sed 's/$/GB/'
2.52665GB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, I know that if I decide to upgrade my Ubuntu box, it will take up at least 2.5 GB of space!&lt;/p&gt;

</description>
      <category>apt</category>
      <category>dpkg</category>
      <category>bc</category>
    </item>
    <item>
      <title>Calculating total size of disks</title>
      <dc:creator>gunitinug</dc:creator>
      <pubDate>Tue, 26 Mar 2024 00:54:55 +0000</pubDate>
      <link>https://forem.com/gunitinug/calculating-total-size-of-disks-4168</link>
      <guid>https://forem.com/gunitinug/calculating-total-size-of-disks-4168</guid>
      <description>&lt;p&gt;This is the output of &lt;code&gt;lsblk&lt;/code&gt; command on my Ubuntu machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0    7:0    0   1.7G  1 loop /snap/0ad/592
...
sda      8:0    0 111.8G  0 disk 
├─sda1   8:1    0   619M  0 part /boot/efi
├─sda2   8:2    0   954M  0 part [SWAP]
└─sda3   8:3    0 110.3G  0 part /home
sdb      8:16   0 931.5G  0 disk 
└─sdb1   8:17   0 931.5G  0 part /
sr0     11:0    1 383.5M  0 rom  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wanted to get total size of disks &lt;code&gt;sda&lt;/code&gt; and &lt;code&gt;sdb&lt;/code&gt; together, but I wanted to use bash to do it.&lt;/p&gt;

&lt;p&gt;First, I only get lines beginning with &lt;code&gt;sda&lt;/code&gt; or &lt;code&gt;sdb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lsblk | grep -Pi '^sda|^sdb'
sda      8:0    0 111.8G  0 disk 
sdb      8:16   0 931.5G  0 disk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we isolate just the fourth column delimited by spaces (that is SIZE column).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lsblk | grep -Pi '^sda|^sdb' | awk '{print $4}'
111.8G
931.5G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next step would be to add 111.8G and 931.5G together. So we do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lsblk | grep -Pi '^sda|^sdb' | awk '{print $4}' | awk '{total+=$1} END {printf "%.1fG\n",total}'
1043.3G
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, let's convert the answer to terabytes (since the answer is in gigabytes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logan@logan-mainPC:~$ lsblk | grep -Pi '^sda|^sdb' | awk '{print $4}' | awk '{total+=$1} END {printf "%.1fG\n",total}' | awk '{terabyte=$1/1000; printf "%.1fT\n",terabyte}'
1.0T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we conclude that 1043.3G is about 1T in size. Now we know that we would need at least 1T of space to copy the contents of both &lt;code&gt;sda&lt;/code&gt; and &lt;code&gt;sdb&lt;/code&gt; to another hard disk. :)&lt;/p&gt;

</description>
      <category>bash</category>
      <category>awk</category>
      <category>grep</category>
    </item>
  </channel>
</rss>
