Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Linux Tools: The Meaning of Dot

#1
Linux Tools: The Meaning of Dot

<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/linux-tools-the-meaning-of-dot.jpg" width="1500" height="872" title="" alt="" /></div><div><div><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/linux-tools-the-meaning-of-dot.jpg" class="ff-og-image-inserted" /></div>
<p>Let’s face it: writing one-liners and scripts using shell commands can be confusing. Many of the names of the tools at your disposal are far from obvious in terms of what they do (<i>grep</i>, <i>tee</i> and <i>awk</i>, anyone?) and, when you combine two or more, the resulting “sentence” looks like some kind of alien gobbledygook.</p>
<p>None of the above is helped by the fact that many of the symbols you use to build a chain of instructions can mean different things depending on their context.</p>
<h3>Location, location, location</h3>
<p>Take the humble dot (<code>.</code>) for example. Used with instructions that are expecting the name of a directory, it means “this directory” so this:</p>
<pre>
find . -name "*.jpg"
</pre>
<p>translates to “<i>find in this directory (and all its subdirectories) files that have names that end in <code>.jpg</code></i>“.</p>
<p>Both <code>ls .</code> and <code>cd .</code> act as expected, so they list and “change” to the current directory, respectively, although including the dot in these two cases is not necessary.</p>
<p>Two dots, one after the other, in the same context (i.e., when your instruction is expecting a directory path) means “<i>the directory immediately above the current one</i>“. If you are in <i>/home/your_directory</i> and run</p>
<pre>
cd ..
</pre>
<p>you will be taken to <i>/home</i>. So, you may think this still kind of fits into the “dots represent nearby directories” narrative and is not complicated at all, right?</p>
<p>How about this, then? If you use a dot at the beginning of a directory or file, it means the directory or file will be hidden:</p>
<pre>
$ <b>touch somedir/file01.txt somedir/file02.txt somedir/.secretfile.txt</b>
$ <b>ls -l somedir/</b>
total 0 -rw-r--r-- 1 paul paul 0 Jan 13 19:57 file01.txt -rw-r--r-- 1 paul paul 0 Jan 13 19:57 file02.txt $ # Note how there is no .secretfile.txt in the listing above
$ <b>ls -la somedir/</b>
total 8 drwxr-xr-x 2 paul paul 4096 Jan 13 19:57 . drwx------ 48 paul paul 4096 Jan 13 19:57 .. -rw-r--r-- 1 paul paul 0 Jan 13 19:57 file01.txt -rw-r--r-- 1 paul paul 0 Jan 13 19:57 file02.txt -rw-r--r-- 1 paul paul 0 Jan 13 19:57 .secretfile.txt
$ # The -a option tells ls to show "all" files, including the hidden ones
</pre>
<p>And then there’s when you use <code>.</code> as a command. Yep! You heard me: <code>.</code> is a full-fledged command. It is a synonym of <code>source</code> and you use that to execute a file in the current shell, as opposed to running a script some other way (which usually mean Bash will spawn a new shell in which to run it).</p>
<p>Confused? Don’t worry — try this: Create a script called <i>myscript</i> that contains the line</p>
<pre>
myvar="Hello"
</pre>
<p>and execute it the regular way, that is, with <code>sh myscript</code> (or by making the script executable with <code>chmod a+x myscript</code> and then running <code>./myscript</code>). Now try and see the contents of <code>myvar</code> with <code>echo $myvar</code> (spoiler: You will get nothing). This is because, when your script plunks “<i>Hello</i>” into <code>myvar</code>, it does so in a separate bash shell instance. When the script ends, the spawned instance disappears and control returns to the original shell, where <code>myvar</code> never even existed.</p>
<p>However, if you run <i>myscript</i> like this:</p>
<pre>
. myscript
</pre>
<p><code>echo $myvar</code> will print <i>Hello</i> to the command line.</p>
<p>You will often use the <code>.</code> (or <code>source</code>) command after making changes to your <i>.bashrc</i> file, <a href="https://www.linux.com/blog/learn/2018/12/bash-variables-environmental-and-otherwise">like when you need to expand your <code>PATH</code> variable</a>. You use <code>.</code> to make the changes available immediately in your current shell instance.</p>
<h3>Double Trouble</h3>
<p>Just like the seemingly insignificant single dot has more than one meaning, so has the double dot. Apart from pointing to the parent of the current directory, the double dot (<code>..</code>) is also used to build sequences.</p>
<p>Try this:</p>
<pre>
echo {1..10}
</pre>
<p>It will print out the list of numbers from 1 to 10. In this context, <code>..</code> means “<i>starting with the value on my left, count up to the value on my right</i>“.</p>
<p>Now try this:</p>
<pre>
echo {1..10..2}
</pre>
<p>You’ll get <i>1 3 5 7 9</i>. The <code>..2</code> part of the command tells Bash to print the sequence, but not one by one, but two by two. In other words, you’ll get all the odd numbers from 1 to 10.</p>
<p>It works backwards, too:</p>
<pre>
echo {10..1..2}
</pre>
<p>You can also pad your numbers with 0s. Doing:</p>
<pre>
echo {000..121..2}
</pre>
<p>will print out every even number from 0 to 121 like this:</p>
<pre>
000 002 004 006 ... 050 052 054 ... 116 118 120 </pre>
<p>But how is this sequence-generating construct useful? Well, suppose one of your New Year’s resolutions is to be more careful with your accounts. As part of that, you want to create directories in which to classify your digital invoices of the last 10 years:</p>
<pre>
mkdir {2009..2019}_Invoices
</pre>
<p>Job done.</p>
<p>Or maybe you have a hundreds of numbered files, say, frames extracted from a video clip, and, for whatever reason, you want to remove only every third frame between the frames 43 and 61:</p>
<pre>
rm frame_{043..61..3}
</pre>
<p>It is likely that, if you have more than 100 frames, they will be named with padded 0s and look like this:</p>
<pre>
frame_000 frame_001 frame_002 ...
</pre>
<p>That’s why you will use <code>043</code> in your command instead of just <code>43</code>.</p>
<p>Curly~Wurly</p>
<p>Truth be told, the magic of sequences lies not so much in the double dot as in the sorcery of the curly braces (<code>{}</code>). Look how it works for letters, too. Doing:</p>
<pre>
touch file_{a..z}.txt
</pre>
<p>creates the files <i>file_a.txt</i> through <i>file_z.txt</i>.</p>
<p>You must be careful, however. Using a sequence like <code>{Z..a}</code> will run through a bunch of non-alphanumeric characters (glyphs that are neither numbers or letters) that live between the uppercase alphabet and the lowercase one. Some of these glyphs are unprintable or have a special meaning of their own. Using them to generate names of files could lead to a whole bevy of unexpected and potentially unpleasant effects.</p>
<p>One final thing worth pointing out about sequences encased between <code>{...}</code> is that they can also contain lists of strings:</p>
<pre>
touch {blahg, splurg, mmmf}_file.txt
</pre>
<p>Creates <i>blahg_file.txt</i>, <i>splurg_file.txt</i> and <i>mmmf_file.txt</i>.</p>
<p>Of course, in other contexts, the curly braces have different meanings (surprise!). But that is the stuff of another article.</p>
<h3>Conclusion</h3>
<p>Bash and the utilities you can run within it have been shaped over decades by system administrators looking for ways to solve very particular problems. To say that sysadmins and their ways are their own breed of special would be an understatement. Consequently, as opposed to other languages, Bash was not designed to be user-friendly, easy or even logical.</p>
<p>That doesn’t mean it is not powerful — quite the contrary. Bash’s grammar and shell tools may be inconsistent and sprawling, but they also provide a dizzying range of ways to do everything you can possibly imagine. It is like having a toolbox where you can find everything from a power drill to a spoon, as well as a rubber duck, a roll of duct tape, and some nail clippers.</p>
<p>Apart from fascinating, it is also fun to discover all you can achieve directly from within the shell, so next time we will delve ever deeper into how you can build bigger and better Bash command lines.</p>
<p>Until then, have fun!</p>
</div>
Reply



Forum Jump:


Users browsing this thread:
3 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016