<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Bart Busschots &#187; Computers</title>
	<atom:link href="http://www.bartbusschots.ie/blog/?cat=12&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.bartbusschots.ie/blog</link>
	<description>An Irish Voice in the Blogsphere</description>
	<lastBuildDate>Sat, 18 May 2013 20:03:55 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Thanks Tim</title>
		<link>http://www.bartbusschots.ie/blog/?p=2456</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2456#comments</comments>
		<pubDate>Sat, 18 May 2013 19:41:33 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Obituary]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2456</guid>
		<description><![CDATA[This is not going to be an easy post to write, and I really hope I do it justice. The Apple/Mac community lost one of it&#8217;s finest podcasters today. Tim Verpoorten wasn&#8217;t the first Apple/Mac podcaster, but he was one of the very earliest generation. I think it would be fair to call him a [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/05/TimVerpoorten.jpg" alt="Tim Verpoorten" title="TimVerpoorten.jpg"  width="306" height="358" style="float:right;margin:3px;border-width:0px" />This is not going to be an easy post to write, and I really hope I do it justice.</p>
<p>The Apple/Mac community lost one of it&#8217;s finest podcasters today. Tim Verpoorten wasn&#8217;t the first Apple/Mac podcaster, but he was one of the very earliest generation. I think it would be fair to call him a father figure to many of us who followed. I know he was one of the podcasters who inspired me to pick up the microphone myself, and I doubt I&#8217;m alone in that.</p>
<p>Tim had been unwell for some time, and hung up his microphone to concentrate on his health a while ago, but we all hoped it would just be a temporary hiatus. I don&#8217;t think any of us in the community wanted to believe  we&#8217;d heard the last of Tim&#8217;s distinctive and friendly voice.</p>
<p>Every good Apple/Mac podcast brings something unique to the table, and Tim&#8217;s Mac Review Cast brought fantastic reviews week after week after week for years and years. Tim had a knack for finding great apps, particularly free ones, and he was able to find and review them at a truly impressive rate. Most people can mange either quantity or quality, but Tim could do both at the same time. Although he reviewed many many apps, you could always tell when an app really appealed to him. Those apps were almost never large apps with lots of features, but small apps that did just one thing, but did it really well. It&#8217;s fair to say Tim had a bit of a thing for menubar apps.</p>
<p>Because I learned about so many great apps on the Mac Review Cast, I regularly look up at my menu bar, or into my dock, and think of Tim. One app in particular that I&#8217;ll always associate with him is the light-weight Mac-like text editor Smultron. I&#8217;d almost given up on finding an editor like this for the Mac, when I heard Tim review Smultron, and gave it a go. It was love at first sight, and that cute red strawberry icon will always bring back fond memories of Tim.</p>
<p>Tim was one of the founders of the Mac Round Table Podcast (MRT), and it was through that podcast that I was fortunate enough to get to &#8216;work&#8217; (play more like) with Tim. One of the great things about the MRT is how different all the contributors are, and how that opens up some great conversations. We often agreed on things, but when it comes to temperament, I think myself and Tim were polar opposites &#8211; I&#8217;m know for being the cranky Irishman (sorta) who&#8217;s prone to impassioned (and hopefully entertaining) rants, while Tim was always as cool as a cucumber &#8211; I can&#8217;t remember him ever getting flapped, and I can&#8217;t remember him ever having a bad word to say about anyone. I think it&#8217;s much easier to go on a rant than it is to remain calm and collected, and I greatly admired Tim&#8217;s coolness.</p>
<p>I never met Tim in the real world, yet I feel I&#8217;ve lost a friend.  The Mac community has certainly lost one of it&#8217;s finest ambassadors, but my thoughts are with the Verpoorten family tonight &#8211; their loss is so much greater than ours.</p>
<p style="font-style:italic">The photo that accompanies this post is a crop from <a href="http://www.flickr.com/photos/nosillacast/4351409513/" target="_blank">this image</a> by <a href="http://www.podfeet.com" target="_blank">Allison Sheridan</a>.</p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2456</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Taming the Terminal Part 3 of n</title>
		<link>http://www.bartbusschots.ie/blog/?p=2439</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2439#comments</comments>
		<pubDate>Sat, 11 May 2013 19:28:55 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux, GNU & FOSS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[Terminal]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2439</guid>
		<description><![CDATA[This is the third instalment of an on-going series. These blog posts are only part of the series, they are actually the side-show, being effectively just my show notes for discussions with Allison Sheridan on my bi-weekly Chit Chat Across the Pond segment on her show, the NosillaCast Mac Podcast. This instalment will be featured [...]]]></description>
				<content:encoded><![CDATA[<p><img style="float: right; margin: 3px; border-width: 0px;" title="TamingTheTerminal.png" alt="Taming the Terminal" src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/TamingTheTerminal.png" width="300" height="224" />This is the third instalment of an on-going series. These blog posts are only part of the series, they are actually the side-show, being effectively just my show notes for discussions with Allison Sheridan on my bi-weekly Chit Chat Across the Pond segment on her show, <a href="http://www.podfeet.com/" target="_blank">the NosillaCast Mac Podcast</a>. This instalment will be featured in NosillaCast episode 418 (scheduled for release late on Sunday the 12th of May 2013).</p>
<p>In the <a href="http://www.bartbusschots.ie/blog/?p=2413" target="_blank">first installment</a> we started with the 40,000ft view, looking at what command shells are, and why they&#8217;re still relevant in today&#8217;s GUI-dominated world. In the <a href="http://www.bartbusschots.ie/blog/?p=2422" target="_blank">second instalment</a> we looked at OS X&#8217;s Terminal.app, the anatomy of the Bash command prompt, and the anatomy of a Unix/Linux command. This time we&#8217;ll be looking at the anatomy of file systems in general, and the Unix/Linux file system in particular, and how it differs from the Windows/DOS file system many of us grew up using.</p>
<p><span id="more-2439"></span></p>
<p>Physical storage media are nothing more than a massive array of virtual pigeon holes, each of which can hold a single 1 or 0. All your information is stored by grouping together a whole bunch of these pigeon holes and giving that grouping of 1s and 0s some kind of name. Humans simply could not deal with remembering that the essay they were working on is stored in sectors 4 to 1024 on cylinder 213 on the disk connected to the first SATA channel on the motherboard. We need some kind of abstraction to bring order to the chaos and to allow us to organise our data in a human-friendly way.</p>
<p>A good analogy would be a pre-computer office where the unit of storage was a single sheet of paper. Without some sort of logical system for organising all this paper no one would ever be able to find anything, hence, in the real world we developed &#8216;systems&#8217; for &#8216;filing&#8217; paper. Or, to put it another way, we invented physical filesystems, based around different ways of grouping and naming the pieces of paper. If a single document contained so much information that it ran over multiple pages, those piece of paper were physically attached to each other using a tie, a paperclip, or a staple. To be able to recognise a given document at a glance, documents were given titles. Related documents were then put together into holders that, for some reason were generally green, and those holders were then placed into cabinets with rails designed to hold the green holders in an organised way. I.e. we had filing cabinets containing folders which contained files. The exact organisation of the files and folders were up to the individual clerks who managed the data, and were dependant on the kind of data being stored. Doctors tend to store files alphabetically by surname, while libraries love the <a href="http://en.wikipedia.org/wiki/Dewey_Decimal_Classification" target="_blank">Dewey Decimal</a> system.</p>
<p>When it comes to computers, the job of bringing order to the chaos falls to our operating systems. We call the many different schemes that have been devised to provide that order filesystems. Some filesystems are media dependent, while others are operating system dependent. E.g. the <a href="http://en.wikipedia.org/wiki/Joliet_(file_system)" target="_blank">Joliet file system </a>is used on CDs and DVDs regardless of OS, while <a href="http://en.wikipedia.org/wiki/File_Allocation_Table" target="_blank">FAT</a> and <a href="http://en.wikipedia.org/wiki/NTFS" target="_blank">NTFS</a> are Windows filesystems, <a href="http://en.wikipedia.org/wiki/Extended_file_system" target="_blank">EXT</a> is a family of Linux file systems, and <a href="http://en.wikipedia.org/wiki/HFS%2B" target="_blank">HFS+</a> is a Mac file system.</p>
<p>There are an infinite number of possible ways computer scientists could have chosen to bring order to the chaos of bits on our various media, but, as is often the case, a single real-world analogy was settled on by just about all operating system authors. Whether you use Linux, Windows, or OS X, you live in a world of filesystems that contain folders (AKA directories) that contain files and folders. Each folder and file in this recursive hierarchical structure has a name, so it allows us humans to keep our digital documents organised in a way that we can get our heads around. Although all our modern filesystems have their own little quirks under the hood, they all share the same simple architecture, your data goes in files which go in folders which can go in other folders which eventually go into file systems.</p>
<p>You can have lots of files with the same name in this kind of file system, but, you can never have two items with the same name in the same folder. This means that each file and folder can be uniquely identified by listing all the folders you pass to get from the so-called &#8216;root&#8217; of the filesystem as far as the file or folder you are describing. This is what we call the full path to a file or folder. On all modern consumer operating systems we write file paths as a list of folder and file names separated by some character, called the &#8216;path separator&#8217;. Where operating systems diverge is in their choice of separator, and in the rules they impose on file and folder names. DOS and Windows use <code>\</code> (the backslash) as the path separator, on classic MacOS it was <code>:</code> (old OS X apps that use Carbon instead of Cocoa still use <code>:</code> when showing file paths, iTunes did this up until the recent version 11!), and on Linux/Unix(including OS X), <code>/</code> (the forward-slash) is used.</p>
<p>A single floppy disk and a single CD or DVD contain a single file system to hold all the data on a given disk, but that&#8217;s not true for hard drives, thumb drives, or networks. When formatting our hard drives or thumb drives we can choose to sub-divide a single physical device into multiple so-called partitions, each of which will then contain a single filesystem.</p>
<p>You&#8217;ve probably guessed by now that on our modern computers we tend to have more than one filesystem. Even if we only have one internal hard disk in our computer that has been formatted to have only a single partition, every CD, DVD, or thumb drive we own contains a filesystem, and, each network share we connect to is seen by our OS as yet another file system. In fact, we can even choose to store an entire filesystem (even an encrypted one) in a single file, e.g. DMG files, or TrueCrypt vaults.</p>
<p>So, all operating systems have to merge lots of file systems into a single over-arching namespace for their users. Or, put another way, even if two files have identical paths on two filesystems mounted by the OS at the same time, there has to be a way to distinguish them from each other. There are lots of different ways you could combine multiple filesystems into a single unified namespace, and this is where the DOS/Windows designers parted ways with the Unix/Linux folks. Microsoft combines multiple file systems together in a very different way to Unix/Linux/OS X.</p>
<p>Lets start by looking at the approach Microsoft chose to. In DOS, and later Windows, each filesystem is presented to the user as a separate island of data named with a single letter, referred to as a <em>drive letter</em>. THis approaches has an obvious limitation, you can only have 26 file systems in use at any one time! For historical reasons, <code>A:\</code> and <code>B:\</code> were reserved for floppy drives, so, the first partition on the hard drive connected to the first IDE/SATA bus on the motherboard is given the drive letter <code>C:\</code>, the second one <code>D:\</code> and so on. When ever you plug in a USB thumb drive or a memory card from a camera it gets &#8216;mounted&#8217; on the next free drive letter. Network shares also get mounted to drive letters.</p>
<p>Just like files and folders, filesystems themselves have names too, often referred to as <em>Volume Names</em>. Windows makes very little use of these volume names though, they don&#8217;t show up in file paths, but, Windows Explorer will show them in some situations to help you figure out which of your USB hard drives ended up as K:\ today.</p>
<p>An analogy you can use for file systems is that of a tree. The trunk of the tree is the base of the file system, each branch is a folder, and each leaf a file. Branches &#8216;contain&#8217; branches and leaves, just like folders contain folders and files. If you bring that analogy to Microsoft&#8217;s way of handling filesystems, then the global namespace is not a single tree, but a small copse of between 1 and 26 trees, each a separate entity, and each named with a single letter.</p>
<p>If we continue this analogy, Linux/Unix doesn&#8217;t plant a little copse of separate trees DOS/Windows does, instead they construct one massive franken-tree by grafting smaller trees onto the branches of a single all-containing master tree. When Linux/Unix boots, one filesystem is considered to be the main filesystem, and used as the master file system into which other file systems get inserted as folders. In OS X parlance, we call the partition containing this master file system the <em>System Disk</em>. Because the system disk becomes the root of the entire filesystem it is gets assigned the shortest possible file path, <code>/</code>.</p>
<p>If your system disk&#8217;s file system contained just two folders, <code>folder_1</code> and <code>folder_2</code>, they would get the file paths <code>/folder_1/</code> and <code>/folder_2/</code> in Linux/Unix/OS X. The Unix/Linux command <code>mount</code> can then be used to &#8216;graft&#8217; filesystems into the master filesystem using any empty folder as the so-called <code>mount point</code>.</p>
<p>On Linux systems it&#8217;s common practice to keep home folders on a separate partition, and to then mount that separate partition&#8217;s file system as <code>/home/</code>. This means that the main filesystem has an empty folder in it called <code>home</code>, and that as the computer boots, the OS mounts a specified partition&#8217;s file system into that folder. A folder at the root of the that partition&#8217;s file system called just <code>allison</code> would then become <code>/home/allison/</code>.</p>
<p>On regular Linux/Unix distributions the file <code>/etc/fstab</code> (file system table) tells the OS what filesystems to mount to what mount points. A basic version of this file will be created by the installer, but in the past, when ever you added a new disk to a Linux/Unix system you had to manually edit this file. Thankfully, we now have something called <code>automount</code> to automatically mount any readable filesystems to a pre-defined location on the filesystem when they are connected.</p>
<p>The exact details will change from OS to OS, but on Ubuntu, the folder <code>/media/</code> is used to hold mount points for any file system you connect to the computer. Unlike Windows, most Linux/Unix systems make use of filesystems&#8217; volume names, and use them to give the mount points sensible names, rather than random letters. If I connect a USB drive containing a single partition with a filesystem with the volume name <code>Allison_Pen_Drive</code>, Ubuntu will automatically mount the filesystem on that thumb drive when you plug it in, using the mount point <code>/media/Allison_Pen_Drive/</code>. If that pen drive contained a single folder called <code>myFolder</code> containing a single file called <code>myFile.txt</code>, then <code>myFile.txt</code> would be added to the filesystem as <code>/media/Allison_Pen_Driver/myFolder/MyFile.txt</code>.</p>
<p>Having the ability to mount any filesystem as any folder within a single master filesystem allows you to easily separate different parts of your OS across different drives. This is very useful if you are a Linux/Unix sysadmin or power user, but it can really confuse regular users. Because of this, OS X took a simpler route. There is no <code>/etc/fstab</code> (actually, there sort of is, but it just contains some text telling you that the file does nothing and not to use it &#8211; for a LOL try typing <code>cat /etc/fstab.hd</code> into a terminal). The OS X installer does not allow you to split OS X over multiple partitions, everything belonging to the OS X system, including all the users home folders, are installed on a single partition, the system disk, and all other file systems, be they internal, external, network, or disk images, get automatically mounted in <code>/Volumes/</code> as folders named for the file systems&#8217; volume labels.</p>
<p>Going back to our imaginary thumb drive called <code>Allison_Pen_Drive</code> (which Ubuntu would mount as <code>/media/Allison_Pen_Drive/</code>), OS X will mount that as <code>/Volumes/Allison_Pen_Drive/</code> when you plug it in. If you had a second partition, or a second internal drive, called, say, <code>Fatso</code> (a little in-joke for Allison), OS X would mount that as /<code>Volumes/Fatso/</code>. Likewise, if you double-clicked on a DMG file you downloaded from the net, say with the Adium installer, OS X would mount that as something like <code>/Volumes/Adium/</code> until you eject the DMG. The &#8216;disks&#8217; listed in the Finder side bar in the section headed <code>Devices</code> are just links to the contents of <code>/Volumes/</code>. You can see this for yourself by opening a Finder Window and either hitting the key-combo <code>cmd+shift+g</code>, or navigating to <code>Go→Go To Folder ...</code> in the menubar to bring up the <code>Go To Folder</code> text box, and then typing the path <code>/Volumes</code> and hitting return.</p>
<p>OS X&#8217;s greatly simplified handling of mount points definitely makes OS X less confusing, but, the simplicity comes at a price. If you DO want to do more complicated things like have your home folders on a separate partition, you are stepping outside of what Apple consider the norm, and into a world of pain. On Linux/Unix separating out home folders is trivial, on OS X it&#8217;s a mine-field!</p>
<p>We&#8217;ll leave it here for now, next time we&#8217;ll learn how to navigate around a Unix/Linux/OS X filesystem.</p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2439</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Taming the Terminal &#8211; Part 2 of n</title>
		<link>http://www.bartbusschots.ie/blog/?p=2422</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2422#comments</comments>
		<pubDate>Fri, 26 Apr 2013 21:41:30 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux, GNU & FOSS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[Terminal]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2422</guid>
		<description><![CDATA[This is the second instalment of an on-going series. In the first instalment I tried to give you a sort of 40,000ft view of command shells &#8211; some context, some history, a very general description of what command shells do, and a little bit on why they are still very useful in the modern GUI [...]]]></description>
				<content:encoded><![CDATA[<p><img style="float: right; margin: 3px; border-width: 0px;" title="TamingTheTerminal.png" alt="Taming the Terminal" src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/TamingTheTerminal.png" width="300" height="224" />This is the second instalment of an on-going series. In <a href="http://www.bartbusschots.ie/blog/?p=2413" target="_blank">the first instalment</a> I tried to give you a sort of 40,000ft view of command shells &#8211; some context, some history, a very general description of what command shells do, and a little bit on why they are still very useful in the modern GUI age. The most important points to remember from last time are that command shells execute commands, that there are lots of different command shells on lots of different OSes, but that we will be focusing on <a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)" target="_blank">Bash</a> on Linux/Unix in general, and Bash on OS X in particular. The vast majority of topics I plan to discuss in these segments will be applicable on any system that runs Bash, but, the screen shots I use will be from OS X, and some of the cooler stuff will be OS X only. This segment, like all the others will be used as part of my bi-weekly Chit Chat Across The Pond (CCATP) segment with Allison Sheridan on <a href="http://www.podfeet.com/" target="_blank">the NosillaCast Mac Podcast</a>.</p>
<p>Last time I focused on the shell, and avoided getting in any way specific about the actual commands that we will be executing within the Bash shell. I thought it was very important to make as clear a distinction between command shells and commands as possible, so I split the two concepts into two separate segments. Having focused on command shells last time, this instalment will focus on the anatomy of a command, but will start with a quick intro to the Terminal app in OS X first.</p>
<p><span id="more-2422"></span></p>
<h3>Introducing the Terminal Window</h3>
<p>You&#8217;ll find Terminal.app in <code>/Applications/Utilities</code>. Unless you&#8217;ve changed some of the default settings (or are using a very old version of OS X), you will now see a white window that is running the bash command shell that looks something like this:</p>
<p style="text-align: center;"><img style="border-width: 0px;" alt="An OS X Terminal Window" src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/Screen-Shot-2013-04-26-at-20.47.07.png" width="480" height="337" /></p>
<p>Lets start at the very top of the window with its title bar. At the left of the title is a proxy icon representing the <em>current directory</em> for the current Bash command shell, and beside it the name of that folder. (Note that <em>directory</em> is the Unix/Linux/DOS word for what OS X and Windows refers to as a <em>folder</em>.) Like Finder windows, Terminal sessions are always &#8220;in&#8221; a particular directory/folder. After the current directory will be a dash, followed by the name of the process currently running in the Terminal session (in our case, a bash shell). The current process is followed by another dash, and then the dimensions of the window in fixed-width characters.</p>
<p>Within the window itself you will likely see a line of output telling you when you last logged in, and from where (if it was on this computer it will say ttys followed by some number, if it was from another computer, it will give the computer&#8217;s hostname). This will be followed on the next line by the so-called <em>command prompt</em>, and then the input cursor.</p>
<p style="text-align: center;"><img style="border-width: 0px;" alt="The Anatomy of a Terminal Window" src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/Screenshot_26_04_2013_20_28.png" width="490" height="364" /></p>
<p>Lets have a closer look at the command prompt. As with almost everything in Linux/Unix, the prompt is entirely customisable, so although Bash is the default shell on lots of different operating systems, the default prompt on each of those systems can be different. Lets first look at the default Bash command prompt on OS X:</p>
<p style="text-align: center;"><img style="border-width: 0px;" alt="Screen Shot 2013 04 26 at 21 01 29" src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/Screen-Shot-2013-04-26-at-21.01.29.png" width="490" height="95" /></p>
<p>On OS X, the prompt takes the following form:</p>
<p><code><strong><span style="text-decoration: underline;">hostname</span></strong>:<strong><span style="text-decoration: underline;">current_directory</span></strong> <strong><span style="text-decoration: underline;">username</span></strong>$</code></p>
<p>First you have the hostname of the computer on which the command shell is running (defined in <code>System Preferences → Sharing → Computer Name</code>). This might seem superfluous, but it becomes exceptionally useful once you start using ssh to log in to other computers via the Terminal.</p>
<p>The hostname is followed by a <code>:</code> and then the command shell&#8217;s current directory (note that <code>~</code> is short-hand for &#8220;the current user&#8217;s home folder&#8221;, more on this next time).</p>
<p>The current directory is followed by a space, and then the Unix username of the user running the command shell (defined when you created your OS X account, defaults to your first name if available). Finally, there is a <code>$</code> character (which changes to a <code>#</code> when you run bash as the root user). Again, this might not seem very useful at first, but there are many reason you may want to switch your command shell to run as a different user from time to time, so it is also very useful information.</p>
<p>As an example of how the default shells differ on different operating systems, below is an example from a RedHat-style Linux distribution (CentOS in this case):</p>
<p style="text-align: center;"><img style="border-width: 0px;" alt="Default Bash Command Prompt on CentOS" src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/Screen-Shot-2013-04-26-at-21.11.39.png" width="490" height="66" /></p>
<p>As you can see, it contains the same information, but arranged a little differently:</p>
<p><code>[<strong><span style="text-decoration: underline;">username</span></strong>@<strong><span style="text-decoration: underline;">hostname</span></strong> <strong><span style="text-decoration: underline;">current_directory</span></strong>]$</code></p>
<p>Finally, Debian-style Linux distributions like Ubuntu use a different default promote again, but also showing the same information:</p>
<p style="text-align: center;"><img style="border-width: 0px;" alt="Default Bash Command Prompt on Ubuntu" src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/Screen-Shot-2013-04-26-at-21.16.18.png" width="490" height="67" /></p>
<p><code><strong><span style="text-decoration: underline;">username</span></strong>@<strong><span style="text-decoration: underline;">hostname</span></strong>:<strong><span style="text-decoration: underline;">current_directory</span></strong>$</code></p>
<p><em><strong>Handy Tip:</strong> if you find the text in the Terminal window to small to read, you can make it bigger or smaller with cmd+ or cmd-. This will affect just your current Terminal window. You can permanently change the default by editing the default profile in <code>Terminal → Preferences ... → Settings</code></em></p>
<h3>The Anatomy of a Command</h3>
<p>Now that we understand the different parts of our Terminal window, lets have a look at the structure of the actual commands we will be typing at that cursor!</p>
<p>I want to start by stressing that the commands executed by a command shell are not determined by the command shell, but by the operating system. Regardless of whether you use Bash on OS X, or zsh on OS X, you will have to enter OS X commands. Similarly, if you use Bash on Linux, you will have to enter Linux commands. Thankfully Linux and Unix agree almost entirely on the structure of their basic commands, so with a very few (and very annoying) exceptions, you can use the same basic commands on any Linux or Unix distribution (remember that at its heart OS X is Free BSD Unix).</p>
<p>Commands take the form of the command itself optionally followed by a list of <em>arguments</em> separated by spaces i.e.:</p>
<p><code><strong><span style="text-decoration: underline;">command</span> <span style="text-decoration: underline;">argument_1</span> <span style="text-decoration: underline;">argument_2</span></strong> ... <strong><span style="text-decoration: underline;">argument_n</span></strong></code></p>
<p>Arguments are a mechanism for passing information to a command. Most commands need at least one argument to be able to perform their task, but some don&#8217;t. Both commands and arguments are case-sensitive, so beware your capitalisation!</p>
<p>For example, the <code>cd</code> (change directory) command takes one argument (a directory path):</p>
<pre>bart-imac:~ bart$ <strong>cd /Users/Shared/</strong>
bart-imac:Shared bart$</pre>
<p>In this example, the command is <code>cd</code>, and the one argument passed is <code>/Users/Shared/</code>.</p>
<p>Some commands don&#8217;t require any arguments at all, e.g. the <code>pwd</code> (present working directory) command:</p>
<pre>bart-imac:~ bart$ <strong>pwd</strong>
/Users/bart
bart-imac:~ bart$</pre>
<p>It is up to each command to determine how it will process the arguments it is given. When the developer was creating the command he or she will have had to make decisions about what arguments are compulsory, what arguments are optional, and how to parse the list of arguments the command is given by the shell when being executed.</p>
<p>In theory every developer could come up with their own mad complex scheme for parsing argument lists, but in reality most developers loath re-inventing the wheel (thank goodness), so a small number of standard libraries have come into use for parsing arguments. This means that many apps use very similar argument styles.</p>
<p>As well as accepting simple arguments like the <code>cd</code> command above, many apps accept specially formatted arguments referred to as <code>flags</code>. Flags are usually used to specify optional extra information, with information that is required taken as simple arguments. Flags are arguments (or pairs of arguments) that start with the <code>-</code> symbol.</p>
<p>The simplest kinds of flags are those that don&#8217;t take a value, they are specified using a single argument consisting of a <code>-</code> sign followed by a single letter. For example, the <code>ls</code> (list directory) command can accept the flag <code>-l</code> (long form listing) as an argument. e.g.</p>
<pre>bart-imac:Shared bart$ <strong>ls -l</strong>
total 632
drwxrwxrwx  3 root   wheel     102  5 Dec  2010 Adobe
drwxrwxrwx  3 bart   wheel     102 27 Mar  2012 Library
drwxrwxrwx@ 5 bart   wheel     170 28 Dec 21:24 SC Info
drwxr-xr-x  4 bart   wheel     136 22 Feb 21:42 cfx collagepro
bart-imac:Shared bart$</pre>
<p>The way the standard argument processing libraries work, flags can generally be specified in an arbitrary order. The <code>ls</code> command also accepts the flag -a (list all), so the following are both valid and equivalent:</p>
<pre>bart-imac:Shared bart$ <strong>ls -l -a</strong></pre>
<p>and</p>
<pre>bart-imac:Shared bart$ <strong>ls -a -l</strong></pre>
<p>The standard libraries also allow flags that don&#8217;t specify values to be compressed into a single argument like so:</p>
<pre>bart-imac:Shared bart$ <strong>ls -al</strong></pre>
<p>Sometimes flags need to accept a value, in which case the flag stretches over two arguments which have to be contiguous. For example, the <code>ssh</code> (secure shell) command allows the port to be used for the connection to be specified with the <code>-p</code> flag, and the username to connect as with the <code>-l</code> flag, e.g.:</p>
<pre>bart-imac:Shared bart$ <strong>ssh bw-server.localdomain -l bart -p 443</strong></pre>
<p>These single-letter flags works great for simple commands that don&#8217;t have too many options, but more complex commands often support many tens of optional flags. For that reason another commonly used argument processing library came into use that accepts long-form flags that start with a <code>--</code> instead of a single <code>-</code>. As well as allowing a command to support more flags, these longer form flags also allow values to be set within a single argument by using the <code>=</code> sign.</p>
<p>As an example, the <code>mysql</code> command (needs to be installed separately on OS X) allows the username and password to be used when making a database connection to be specified using long-form flags:</p>
<pre>...$ <strong>mysql --username=bart --password=open123 example_database</strong></pre>
<p>Many commands support both long and short form arguments, and they can be used together, e.g.:</p>
<pre>...$ <strong>mysql --username=bart --password=open123 example_database -v</strong></pre>
<p><code>So far we know that commands consist of a command optionally followed by a list of arguments separated by spaces, and that many Unix/Linux commands use similar schemes for processing arguments where arguments starting with <code>-</code> or <code>--</code> are treated in a special way, and referred to as flags. That all seems very simple, but, there is one important complication that we have to address before finishing up for this segment, and that's special characters.</code></p>
<p>Within Bash (and indeed every other command shell), there are some characters that have a special meaning, so they cannot be used in commands or arguments without signifying to the command shell in some way that is should interpret these symbols as literal symbols, and not as representations of some sort of special value or function.</p>
<p>The most obvious example from what we have learned today is the space character, it is used as the separator between commands and the argument list that follows, and within that argument list as the separator between individual arguments. What if we want to pass some text that contains a space to a command as an argument? This happens a lot because spaces are valid characters within file and folder names on Unix and Linux, and file and folder names are often passed as arguments.</p>
<p>As well as the space there are other symbols that have special meanings. I won&#8217;t explain what they mean today, but I will list them:</p>
<ul>
<li>space</li>
<li><code>#</code></li>
<li><code>;</code></li>
<li><code>"</code></li>
<li><code>'</code></li>
<li><code>`</code></li>
<li><code>\</code></li>
<li><code>!</code></li>
<li><code>$</code></li>
<li><code>(</code></li>
<li><code>)</code></li>
<li><code>&amp;</code></li>
<li><code>&lt;</code></li>
<li><code>&gt;</code></li>
<li><code>|</code></li>
</ul>
<p>You have two choices for how you deal with these special characters when you need to include them within an argument, you can <em>escape</em> each individual special character within the argument, or you can <em>quote</em> the entire argument.</p>
<p>Escaping is easy, you simply pre-fix the special character in question with a <code>\</code>. If there are only one or two special characters in an argument this is the simplest and easiest solution. But, it can become tedious if there are many such special characters.</p>
<p>Lets use the <code>echo</code> command to illustrate escaping. The <code>echo</code> command simply prints out the input it receives. The follow example passes the phrase <em>Hello World!</em> to the echo command as a single argument. Note that this phrase contains two special characters that will need to be escaped, the space and the <code>!</code>:</p>
<pre>bart-imac:~ bart$ <strong>echo Hello\ World\!</strong>
Hello World!
bart-imac:~ bart$</pre>
<p>If you don&#8217;t want to escape each special character in an argument, you can quote the argument by prepending and appending either a <code>"</code> or a <code>'</code> symbol to it. There is a subtle difference between using <code>'</code> or <code>"</code>.</p>
<p>When you quote with <code>'</code> you are doing so-called <em>full quoting</em>, every special character can be used inside a full quote, but, it is impossible to use a <code>'</code> character inside a fully quoted argument. For example:</p>
<pre>bart-imac:~ bart$ <strong>echo '# ;"`\!$()&amp;&lt;&gt;|'</strong>
# ;"`\!$()&amp;&lt;&gt;|
bart-imac:~ bart$</pre>
<p>When you quote with <code>"</code> on the other hand you are doing so-called <em>partial quoting</em>, which means you can use most special characters without escaping them, but not all. Partial quoting will become very important later when we start to use variables and things, because the biggest difference between full and partial quoting is that you can&#8217;t use variable substitution with full quoting, but you can with partial quoting (don&#8217;t worry if that makes no sense at the moment, it will later in the series).</p>
<p>When using partial quoting you still have to escape the following special characters:</p>
<ul>
<li><code>"</code></li>
<li><code>`</code></li>
<li><code>\</code></li>
<li><code>$</code></li>
</ul>
<p>For example:</p>
<pre>bart-imac:~ bart$ <strong>echo "# ;\!()&amp;&lt;&gt;|"</strong>
# ;\!()&amp;&lt;&gt;|
bart-imac:~ bart$</pre>
<p>and:</p>
<pre>bart-imac:~ bart$ <strong>echo "\\ \$ \" \`"</strong>
\ $ " `
bart-imac:~ bart$</pre>
<p>There are a few other peculiar edge cases with partial quoting &#8211; for example, you can&#8217;t end a partial quote with a <code>!</code>, and you can&#8217;t quote just a <code>*</code> on its own (there may well be more edge cases I haven&#8217;t bumped into yet).</p>
<p>That&#8217;s where we&#8217;ll leave it for this segment. We&#8217;ve now familiarised ourselves with the OS X Terminal window, and we&#8217;ve described the anatomy of a Unix/Linux command. In the next segment we&#8217;ll look at the Unix/Linux file system, and at some of the commands used to navigate around it.</p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2422</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Taming the Terminal &#8211; Part 1 of n</title>
		<link>http://www.bartbusschots.ie/blog/?p=2413</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2413#comments</comments>
		<pubDate>Sat, 13 Apr 2013 15:35:31 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux, GNU & FOSS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[Terminal]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2413</guid>
		<description><![CDATA[I have no idea whether or not this idea is going to work out, but on this week&#8217;s Chit Chat Across the Pond segment on the NosillaCast Mac Podcast (to be released Sunday evening PST) I&#8217;m going to try start what will hopefully be an on-going series of short un-intimidating segments to gently introduce Mac [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/TamingTheTerminal.png" alt="Taming the Terminal" title="TamingTheTerminal.png"  width="300" height="224" style="float:right;margin:3px;border-width:0px" />I have no idea whether or not this idea is going to work out, but on this week&#8217;s Chit Chat Across the Pond segment on the <a href="http://www.podfeet.com" target="_blank">NosillaCast Mac Podcast</a> (to be released Sunday evening PST) I&#8217;m going to try start what will hopefully be an on-going series of short un-intimidating segments to gently introduce Mac users to the power contained within the OS X Terminal app. I&#8217;m on with Allison every second week, and I&#8217;ll have other topics to talk about, so the most frequent the instalments in this series could be would be bi-weekly, but I think they&#8217;ll turn out to be closer to monthly on average. While the focus will be on OS X, the majority of the content will be equally applicable to any other Unix or Linux operating system.</p>
<p>In the <a href="http://www.podfeet.com/wordpress/2013/03/31/412-rslsteeper-autismate-audio-hijack-pro-mail-security/" target="_blank">last CCATP</a> we did a very detailed segment on email security, and despite the fact that with the benefit of hind-sight I realise it was too much to do at once and should have been split into two segments, it received the strongest listener response of anything of any of my many contributions to the NosillaCast in the last 5 or more years. I hope I&#8217;m right in interpreting that as evidence that there are a lot of NosillaCast listeners who want to get a little more technical, and get their hands dirty with some good old-fashioned nerdery!</p>
<p><span id="more-2413"></span>
<p>In this first segment I just want to lay a very basic foundation. I plan to take things very slowly with this series, so I&#8217;m going to start the way I mean to continue. Lets start with some history and some wider context.</p>
<p>Before the days of GUIs (Graphical User Interfaces), and even before the days of simple menu-driven non-graphical interfaces like the <a href="http://en.wikipedia.org/wiki/File:Wordperfect-5.1-dos.png" target="_blank">original Word Perfect on DOS</a>, the way humans interacted with computers was through a &#8220;command shell&#8221;. Computers couldn&#8217;t (and still can&#8217;t) speak or interpret human languages properly, and humans find it very hard to speak in native computer languages like binary machine codes (though early programers did actually have to do that), so new languages were invented to help bridge the gap, and allow humans and computers to meet somewhere in the middle. The really big problem is that computers have absolutely no intelligence, so they can&#8217;t deal with ambiguity at all. Command shells use commands that look Englishy, but they have very rigid structures (or grammars if you will) that remove all ambiguity. It&#8217;s this rigid structure that allows the automated translation from shell commands to binary machine code the computer can execute.</p>
<p>When using any command shell, the single most important thing to remember is that computers are absolutely stupid, so they will do EXACTLY what you tell them to, no matter how silly the command you give them. If you tell a computer to delete all the files on a hard drive, it will, because, well, that&#8217;s what you asked it to do! Another important effect of the computers&#8217; total lack of intelligence is that there is no such thing as &#8220;close enough&#8221; &#8211; if you give it a command that&#8217;s nearly valid, a computer can no more execute it than if you&#8217;d just mashed the keyboard with your face. Nearly right and absolute gibberish are just as unintelligible to a computer. You must be exact, and you must be explicit at all times.</p>
<p>No wonder we went on to invent the GUI, this command shell malarky sounds really complicated! There is no doubt that if the GUI hadn&#8217;t been invented the personal computer wouldn&#8217;t have taken off like it has. If it wasn&#8217;t for the GUI there&#8217;s no way there would be more computers than people in my parents home (two of them, and including iPhones and tablets, 6 computers)! Even the nerdiest of nerds use GUI operating systems most of the time, because they make a lot of things both easier and more pleasant. BUT &#8211; not everything.</p>
<p>We all know that a picture says a thousand words, but when you are using a GUI it&#8217;s the computer that is showing you a picture, all you get to do is make crude hand gestures at the computer, which I&#8217;d say is worth about a thousandth of a word &#8211; so, a single shell command can easily be worth a thousand clicks. This is why all desktop OSes still have command shells built in &#8211; not as their ONLY user interface like in times past, but as a window within the GUI environment that lets you communicate with the computer using the power of a command shell. Even Microsoft understands the power of the command shell, DOS may be dead, but the new <a href="http://en.wikipedia.org/wiki/Windows_PowerShell" target="_blank">Windows Power Shell</a> is giving Windows power users a new, more modern, and more powerful command shell than ever before. Windows 8 may have removed the Start menu, but Powershell is still there! All Linux and Unix distros have command shells, and OS X gives you access to an array of different Command Shells through Terminal.app.</p>
<p>Just like there is no one GUI interface, there is no one command shell. Also, just like most GUIs are at least somewhat similar to each other, they all use icons for example, most command shells are also quite similar, having a command prompt that accepts commands with arguments to supply input to the commands or alter their behaviour. OS X does not ship with one command shell, it ships with SIX (<a href="http://en.wikipedia.org/wiki/Bourne_shell" target="_blank">sh</a>, <a href="http://en.wikipedia.org/wiki/Bash_(Unix_shell)" target="_blank">bash</a>, <a href="http://en.wikipedia.org/wiki/Zsh" target="_blank">zsh</a>, <a href="http://en.wikipedia.org/wiki/C_shell" target="_blank">csh</a>, <a href="http://en.wikipedia.org/wiki/Tcsh" target="_blank">tcsh</a>, and <a href="http://en.wikipedia.org/wiki/Korn_shell" target="_blank">ksh</a>)!</p>
<p>You can see the list of available shells (and set your default shell) by opening <code>System Preferences</code>, going to the <code>Users &#038; Groups</code> pref pane, unlocking it, then right-clicking on your username in the side bar, and selecting <code>Advanced Options ...</code>:</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/Screen-Shot-2013-04-13-at-15.29.39.png" alt="Select Advanced Options ..." style="border-width:0px;" width="490" height="241" /></p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2013/04/Screen-Shot-2013-04-13-at-15.30.07.png" alt="Select Login Shell" style="border-width:0px;" width="490" height="387" /></p>
<p>The default shell on OS X is the Bourne Again Shell (bash), so that&#8217;s the shell we&#8217;ll be using for the remainder of this series. If you&#8217;ve not altered the defaults, then when ever you open a Terminal window on OS X, what you&#8217;re presented with is a bash command shell. Bash is an updated and improved version of the older Bourne Shell (sh), which was the default shell in Unix for many years. The original Bourne Shell dates all the way back to 1977, and is called after it&#8217;s creator, <a href="http://en.wikipedia.org/wiki/Stephen_Richard_Bourne" target="_blank">Stephen Bourne</a>. The Bourne Again Shell is a &#8216;newer&#8217; update to the Bourne Shell dating back to 1989, the name being a nerdy religious joke by it&#8217;s author, <a href="http://en.wikipedia.org/wiki/Brian_Fox_(computer_programmer)" target="_blank">Brian Fox</a>. The Bourne Again Shell was not the last in the line of shells tracing their origins to the Bourne Shell, there is also zsh which dates back to 1990, but despite being a more powerful shell, it hasn&#8217;t taken off like bash has.</p>
<p>So, what does a shell do? Does it just let you enter a single command and then run it? Or is there more to it? Unsurprisingly, there&#8217;s a lot more to it! The shell does it&#8217;s own pre-processing before issuing a command for you, so a lot of things that we think of as being part of how a command works, are actually features provided by the command shell. The best example is the almost ubiquitous <code>*</code> symbol. When you issue a command like <code>chmod&nbsp;755&nbsp;*.php</code>, the actual command is not given <code>*.php</code> as a single argument that it must then interpret, no, the <code>*</code> is interpreted and processed by the shell before being passed on to the <code>chmod</code> command. It&#8217;s the shell that goes and looks for all the files in the current folder that end in <code>.php</code>, and replaces the <code>*.php</code> bit of the command with a list of all the actual files that end in <code>.php</code>, and passes that list on to the <code>chmod</code> command.</p>
<p>As well as providing wildcard substitution (the * thing), almost all shells also provide &#8216;plumbing&#8217; for routing command inputs and outputs between commands and files, the definition of variables to allow sequences of commands to be generalised in a more re-usable way, simple programming constructs to enable conditional actions, looping, and the grouping of sequences of commands into named functions, and the execution of a sequence of commands inside a file (scripting), and much more. Different shells also provide their own custom features to help make life at the command prompt easier for users &#8211; my favourite is tab-completion which is the single best thing bash has to offer over sh IMO. OS X also brings some unique features to the table, with superb integration between the GUI and the command shell through features like drag-and-drop support in Terminal.app and shell scripting support Automator. Of all the OSes I&#8217;ve used, OS X is the one that makes it the easiest to integrate command line programs into the GUI.</p>
<p>I&#8217;ll end today by explaining an important part of the Unix philosophy, a part that&#8217;s still very much alive and well within OS X today &#8211; Unix aims to provide a suite of many simple command line tools that each do just one thing, but do it very well &#8211; complex tasks can then be achieved by chaining these simple commands together using a powerful command shell. Each Unix/Linux command line program can be seen as a lego brick &#8211; not all that exciting on their own, but using a bunch of them, you can build fantastic things! My hope for this series is to help readers and listeners like you develop the skills to build your own fantastic things to make your computing lives easier. Ultimately the goal is to help you create more and better things by using automation to free you from as many of your repetitive tasks as possible!</p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2413</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Follow The Money (and beware of digital underpants gnomes)</title>
		<link>http://www.bartbusschots.ie/blog/?p=2409</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2409#comments</comments>
		<pubDate>Sat, 16 Mar 2013 22:43:00 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2409</guid>
		<description><![CDATA[Something that&#8217;s exercised me over the last few years is what I sometimes call &#8220;the tyranny of free&#8221;, because the instance that everything must be free is actually very costly to us all. But, that&#8217;s only part of a bigger picture, and this week&#8217;s announcement from Google that they will be killing a number of [...]]]></description>
				<content:encoded><![CDATA[<p>Something that&#8217;s exercised me over the last few years is what I sometimes call &#8220;the tyranny of free&#8221;, because the instance that everything must be free is actually very costly to us all. But, that&#8217;s only part of a bigger picture, and this week&#8217;s announcement from Google that they will be killing a number of services people have come to rely on, including Google Reader, got me thinking about this again.</p>
<p>I&#8217;ve blogged about <a href="http://www.bartbusschots.ie/blog/?p=2383" target="_blank">the tyranny of free</a> before, so I don&#8217;t want to focus on that today, instead I want to take a step back and talk about the importance of following the money.</p>
<p><span id="more-2409"></span>
<p>When it comes to software we generally don&#8217;t tend to get locked in anymore these days. Not even Office and Photoshop lock you in now. If we are using an app that suddenly goes out of existence, or changes in some way that turns us off, we are almost always free to switch to an alternative app now. So, understanding the finances behind most of the apps we use is not that important. There is one very important caveat though &#8211; apps that act as interfaces to cloud services are very different beasts, because we are using those apps to share our data with a company or organisation.</p>
<p>The really important thing is understanding the financial underpinnings of the cloud services we use. Cloud services are entrusted with a lot of our information, and we can very easily find ourselves locked into them. This is why I think it&#8217;s very important to understand how a service is supposed to make money before starting to use it. In some rare cases like wikipedia, online services are run by non-profit charitable organisations, but in general, services are run by companies, and companies exist to make money. Some people like to fantasise that companies are altruistic beings that are there to serve their admirers, but those are the ravings of fanboys. All companies exist to make money. Apple, Microsoft, FaceBook, Google, Amazon, Evernote, DropBox, Yahoo, Instapaper &#8230;</p>
<p>While all companies exist to make money, all companies are not the same, because there are many different strategies for making money, and those different approaches affect users in very different ways. You can take it for granted that companies exist to make money, what you need to concern yourself with is <strong>how</strong> those companies make their money, because that&#8217;s what will determine the incentives acting on those companies, and affect how they see you and your data.</p>
<p>As strange as it sounds, the first question you have to ask about a company is whether or not they have a business model at all! You&#8217;d imagine that no company could get funding without knowing how it will turn a profit some day, but you&#8217;d be wrong. The digital equivalents of <a href="http://southpark.wikia.com/wiki/Underpants_Gnomes" target="_blank">South Park&#8217;s underpants gnomes</a> are hard at work in silicone valley! Step 1 &#8211; get lots of users, step 3 profit!</p>
<p>When you become dependant on a service that&#8217;s run by digital underpants gnomes you&#8217;re likely to end up suffering in one of two ways. Either, the service collapses because running losses year after year after year is actually a really bad way to run a business. Or, the service changes dramatically once it has attracted enough users to be able to sell them. Sometimes that takes the form of the entire company being sold, e.g. Instagram, and sometimes it takes the form of the company pivoting in some way to convert their users into profit themselves.</p>
<p>Instagram is a good recent example of the first way digital underpants gnomes can convert users into profit, and for me Twitter is the ultimate example of the second. Users, and particularly third party app developers, played a major role in making Twitter the success it is today. Many of the things we consider core features of Twitter were actually developed by third party developers, not Twitter themselves. The two most striking examples are probably the word &#8216;tweet&#8217; (Twitter called them &#8216;twits&#8217; originally), and the concept of @replies. Now, Twitter are pivoting to try sell their user base to advertisers. Originally, they had no customers, now advertisers are their customers. Twitter users are not Twitter&#8217;s customers, they are Twitter&#8217;s product, and the third party developers that played a large part in making Twitter are now a problem that needs to be death with, hence the crushing blows against third part app developers over the last year. As a Twitter user who has relied on a thriving third-party client ecosystem to get a good Twitter experience, I am suffering from Twitter&#8217;s pivot. Had I understood what I do now about the dangers of digital underpants gnomes I&#8217;d never have joined Twitter in the first place.</p>
<p>Assuming the company you&#8217;re evaluating does have a business model, the next key question is who their customers are. The primary concern of any company is to keep their customers happy and coming back for more. It&#8217;s in a company&#8217;s interest to do the things that their customers like, and it&#8217;s against a company&#8217;s interests to upset their customers.</p>
<p>When the users who use a service are also the customers, things are pretty simple &#8211; companies are incentivised to do right by their users. When users are not the customers though, then their interests are inevitably secondary to the interests of the customers, and when the interests of the customers are at odds with the interests of users, then the customers win and users lose out.</p>
<p>Because, for what ever reason, many people in our society want something for nothing, many services rely on advertising as their income stream. This sets up precisely the kind of perverse incentive I worry about. If users were customers then it would be in the company&#8217;s interest to protect their data, but since they are not, that&#8217;s not the case. But, it gets worse, because it is in the advertisers interests to get as much information as possible about the users they are paying to advertise at, so, companies are incentivised to give as much data about their users to their customers, the advertisement agencies, as they can get away with.</p>
<p>Ultimately, we are dealing with market forces here, and as anyone living in a capitalist society knows, market forces are very strong, so when they are working against you, that&#8217;s dangerous.</p>
<p>Perhaps it might be helpful to look at some real-world examples. Please bear in mind that these are my personal opinions, obviously I think I&#8217;m right, but I could of course be wrong.</p>
<ol>
<li><strong>FaceBook</strong> &#8211; it seldom gets more black and white than this IMO. FaceBook&#8217;s customers are advertisers! Recently the lines have gotten a little blurred when FaceBook started to treat some of their users like advertisers by charging to have posts &#8216;promoted&#8217; (i.e shown to all your &#8216;friends&#8217; and not just to a random sub-set of them), but, even still, it seems clear to me that the vast majority of FaceBook users not FaceBook&#8217;s customers, while advertisers clearly are. I think you can understand the way their terms of services have evolved over the years as the inevitable result of the perverse incentives created by having advertisers as their customers rather than their users.</li>
<li><strong>Google</strong> are a little more complicated than FaceBook because they do a lot. They are best know as a search engine, but they are a big service provider too, with extensive cloud offerings, and they also make two operating systems, and a number of apps including a popular browser. They are also stating to directly monetize some of their web services by charging customers for their use. E.g., if you want Google Apps on your own domain, you have to pay now, the free tier has been removed. However, when it comes to making the big money, I think it&#8217;s still all about the ads.</li>
<li><strong>Amazon</strong> &#8211; I find Amazon an interesting case &#8211; they clearly gather a lot of data about their users &#8211; they know everything you search for on their store, and everything you buy there, but they use that data differently to Google, they use it to figure out what else you might like to buy from them via their uncannily good suggestion engine. At first glance, you might think Amazon&#8217;s data gathering is no different to FaceBook&#8217;s, but I think it is, Amazon are not using our data as their product, they are using our data to sell, us, their customers, more of their products, the things they sell in their stores. I sometimes think of Amazon as the digital Wall Mart.
<li>
<li><strong>Apple</strong> are not clear-cut either. They sell hardware, they sell apps, they have a cloud service, and they sell ads. When you look at Apple&#8217;s earnings reports though, it&#8217;s clear that their primary customers are people who buy iThings, followed by people who buy media and software through Apple&#8217;s stores. iAds is really quite insignificant in the grand scheme of things. iCloud is also a very different cloud service to Google&#8217;s. There are no ads, it&#8217;s a freemium service to make iThings more attractive. I think Apple had no choice but to make a free iCloud tier because Google have a free cloud as do Microsoft. Google use their cloud as an ad platform though, while Apple don&#8217;t. On the whole, Apple primarily make their money by selling things to their users, so, Apple&#8217;s users are their main customers.</li>
<li>I find <strong>Microsoft</strong> very difficult to analyse at the moment. Historically they were very easy to understand, they made software, and they primarily sold it to corporate IT departments. You could see by their feature sets that corporate IT was who Microsoft focused on. Now It&#8217;s very hard to tell what Microsoft&#8217;s focus is. They still do the software thing, and they still sell to corporate IT, but, they are also trying to copy Google and become a search and advertisement company, and they are also starting to focus on end-users as well as corporate IT with the XBox and their new phones and tablets. The fact that ads are starting to infest XBox Live shows how complicated the incentives are. I&#8217;m not sure if even Microsoft know what their long-term strategy is, so it&#8217;s very hard to divine what incentives are driving Microsoft&#8217;s decisions, and how they will affect users going forward.</li>
<li><strong>Evernote</strong> and <strong>DropBox</strong> both have, and have had for a long time, business models that work by selling a premium services to a small number of their users, while offering a free service to many more users to help support their ecosystem. Free users on Evernote and DropBox are not their products though, they are their market. The hope is not to sell free users&#8217; data for profit, but to turn a few percent of those free users into paying customers. Those that never sign up are still adding value to the products because both consider easy sharing an important feature, and you can&#8217;t expect people to want to share with you if it will cost them! One of the reasons I chose to trust dropbox with my data is that I heard an interview with their CEO on a podcast where he explained their business model candidly I was impressed that even from the early days they knew where their incentives lay, and I thought they were healthy incentives.</li>
<li><strong>Flickr</strong>, <strong>SmugMug</strong> and <strong>500px</strong> also have a similar model to DropBox and EverNote, while Picassa by contrast has a very different model, and can be thought of as the GMail of photosharing.</li>
<p>The bottom line is that I&#8217;m not interested in telling people what companies or services to choose. Different people will make different decisions based on the same data because we all have different priorities. My hope is that people will stop, investigate, and think, before signing up to a service. It doesn&#8217;t matter what decision you make, as long as it&#8217;s an informed one &#8211; so follow the money before you invest your time and data into a cloud service! Oh, and watch out for those digital underpants gnomes too <img src='http://www.bartbusschots.ie/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2409</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OS X Service for Stripping Geotags from JPEG Images</title>
		<link>http://www.bartbusschots.ie/blog/?p=2393</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2393#comments</comments>
		<pubDate>Sat, 29 Dec 2012 17:57:41 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[EXIFTool]]></category>
		<category><![CDATA[geotagging]]></category>
		<category><![CDATA[OS X]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2393</guid>
		<description><![CDATA[Back in 2011 I wrote a blog post explaining how to create an OS X Service for stripping keywords from image files. In this post we&#8217;ll use the same technique to create a Service for stripping geotags from JPEG images. As with the keyword stripping service, there are two prerequisites for this action, one is [...]]]></description>
				<content:encoded><![CDATA[<p>Back in 2011 I wrote a <a href="http://www.bartbusschots.ie/blog/?p=1906" target="_blank">blog post explaining how to create an OS X Service for stripping keywords from image files</a>. In this post we&#8217;ll use the same technique to create a Service for stripping geotags from JPEG images.</p>
<p>As with the keyword stripping service, there are two prerequisites for this action, one is required, one is optional. You absolutely MUST have install <a href="http://www.sno.phy.queensu.ca/~phil/exiftool/install.html#OSX" target="_blank">EXIFTool</a> installed, and it would be good if you also had <a href="https://itunes.apple.com/us/app/growl/id467939042?mt=12&#038;ign-mpt=uo%3D4" target="_blank">Growl</a> installed, but it&#8217;s not essential.</p>
<p><span id="more-2393"></span>
<p>Start by opening Automator, and creating a new <code>Service</code> workflow.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/12/Screen-Shot-2012-12-29-at-16.48.05.png" alt="Create New Service Workflow in Automator" style="border-width:0px;" width="458" height="490" /></p>
<p>At the top of the new service workflow, alter the settings so the services takes as it&#8217;s input <code>Image Files</code> and that the service is available in just the Finder.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/12/Screen-Shot-2012-12-29-at-16.51.15.png" alt="Set The Service to Accept Image Files in Finder" style="border-width:0px;" width="490" height="90" /></p>
<p>Find the Run Shell Script action and drag and drop it into the workflow (you&#8217;ll find the action in the Utilities category, or by searching in the search bar). Change the <code>Shell</code> option at the top of the <code>Run Shell Script</code> action to <code>/usr/bin/perl</code>, and the <code>Pass input</code> option to <code>as arguments</code>.</p>
<p>To do the actual work we will add the following perl code into the action:</p>
<div id="ig-sh-1" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #b1b100;">foreach</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$image</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">@</span><span style="color: #000000; font-weight: bold;">ARGV</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #0000ff;">$image</span> <span style="color: #339933;">=</span> quote_file_name<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$image</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #ff0000;">`/usr/bin/exiftool -geotag= -overwrite_original $image`</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #009900;">&#125;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># utility function to sanitise file names for use when shelling out</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">sub</span> quote_file_name<span style="color: #009900;">&#123;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$file</span> <span style="color: #339933;">=</span> <span style="color: #000066;">shift</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #0000ff;">$file</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">s/([`&quot;\\\$])/\\$1/g</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; <span style="color: #000066;">return</span> <span style="color: #ff0000;">'&quot;'</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$file</span><span style="color: #339933;">.</span><span style="color: #ff0000;">'&quot;'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #009900;">&#125;</span></div></li>
</ol>	</div></div>
<p>Finally, it would be very helpful to have the service tell us when it is finished, so this is where Growl comes in. If you have it installed, drag and drop a <code>Show Growl Notification</code> into the workflow and enter a message of your choice.</p>
<p>Your Service should now look something like the screenshot below. You can now go ahead and save the Service and give it a sensible name like <code>Strip Geotag</code>.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/12/Screen-Shot-2012-12-29-at-17.17.491.png" alt="Screenshot of the finished Service" style="border-width:0px;" width="490" height="381" /></p>
<p>You should now be able to use the service by right-clicking on a file in the Finder and choosing your new service from the Services section. If you have only a few services installed they will be shown at the bottom of the contextual menu, if you have more, they will show in a sub-menu titled <code>Services</code>.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/12/Screen-Shot-2012-12-29-at-17.21.19.png" alt="The Service in Use in the Finder" style="border-width:0px;" width="490" height="427" /></p>
<p>I&#8217;ve included a zipped version of my service below. This service uses the Growl action, so if you don&#8217;t have Growl installed you&#8217;ll need to open the Service in Automator and remove the Growl action before you can use the Service.</p>
<h3>Download</h3>
<ul>
<li><a href="http://www.bartb.ie/linkStore/blog/AutomatorServices/StripGeotag1.0.zip" target="_blank">Strip Geotag Service Version 1</a> (Requires Growl and EXIFTool)</li>
</ul>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2393</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>End the Tyranny of Free</title>
		<link>http://www.bartbusschots.ie/blog/?p=2383</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2383#comments</comments>
		<pubDate>Sat, 22 Dec 2012 16:36:37 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Polemics, Morality & Politics]]></category>
		<category><![CDATA[The Internet]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2383</guid>
		<description><![CDATA[This week&#8217;s Insgragram TOS kerfuffle is nothing new. Instagram is not the problem, it&#8217;s just the latest symptom of a sick business model that has been allowed to become so dominant as to be almost un-challengeable &#8211; services on the web MUST be free, so you MUST give up your privacy and/or your intellectual property [...]]]></description>
				<content:encoded><![CDATA[<p>This week&#8217;s Insgragram TOS kerfuffle is nothing new. Instagram is not the problem, it&#8217;s just the latest symptom of a sick business model that has been allowed to become so dominant as to be almost un-challengeable &#8211; services on the web MUST be free, so you MUST give up your privacy and/or your intellectual property rights to enable the service providers profits. If you dare stand up for privacy then you are a greedy idiot who wants something for nothing, and you need to grow up and let the companies make money.</p>
<p>My problem is not that companies want to make profits, it&#8217;s their instance on selling our data to do it that I have a problem with. How about this for an idea &#8211; why not let people pay for services rather than insisting we all whore out our privacy and intellectual property?</p>
<p><span id="more-2383"></span>
<p>In the past, when you wanted to set up a company you started with a business plan, and then you went out looking for the money to get your business off the ground. Before you started you knew how you were going to make money. In general, the users of your service were your customers, and you made your money by selling your service to them.</p>
<p>The modern &#8216;web2.0&#8242; approach is different &#8211; you have an idea, you set up a free service (which you bank roll yourself or with &#8216;Angel&#8217; or &#8216;Venture&#8217; capital), you suck in as many users as you can, and then you sell the company to someone else and make a big profit. The whole time you are losing money hand-over-fist. The more popular your free service, the more money you lose, but the more valuable your company becomes. Although it&#8217;s ostensibly the company that is being sold, what&#8217;s really up for sale is the users &#8211; we are the cash-crop of this web2.0 business model.</p>
<p>Even if a free startup decides not to sell, like for example Twitter, the company still has to make the switch from losing to making money, and the way that is done is almost always by exploiting the users.</p>
<p>In order to make your human crop as valuable as possible you need to collect as much personal information about them and their activities as you can, and you need to get them to sign over as many of their rights to you as you can. It&#8217;s this perverse incentive that drives the massive erosion of our privacy that we are seeing at the moment.</p>
<p>It&#8217;s these perverse incentives that the free business model creates that I have such a problem with. As many people have said, if you are not paying for a service, then you are the product. I don&#8217;t want to be anyone&#8217;s product, I want to be their customer!</p>
<p>It&#8217;s true that there are non-free choices for a lot of things online. This blog is not hosted on a free service like Blogger or Tumblr because I want full control over my work, and the information I share. Instead, this blog is hosted on a server I pay for, so I am the customer. My chosen photo network is Flickr, because I can pay them for a pro account and become their customer. Similarly, I have a paid Instapaper account for managing my reading lists, and I pay to use the App.net social network.</p>
<p>However, the tyranny of free still hangs over me. I use many free services because I feel I have to. I have a Twitter account and a G+ account, because as a podcaster you need to be on at least SOME popular social networking sites. I&#8217;ve chosen those two over the likes of FaceBook and LinkedIn because I find their terms and practices the least worrying, but I&#8217;d still love to be able to pay for those services so they could stop selling me on to third parties to make their profit. My videos are hosted on YouTube because that&#8217;s where the community is. I&#8217;m perpetually tempted to switch to Vimeo&#8217;s paid service, but that&#8217;s not where the Irish railway nerds hang out, and YouTube&#8217;s terms are not too odious.</p>
<p>The tyranny of free is also spreading into applications. More and more companies are offering free apps that they then fill with ads. Thankfully there are enough companies that let you pay to remove the ads that I have only one app that I use regularly that is constantly advertising at me. When choosing apps I will always choose the paid alternative over the free add-supported one if I can.</p>
<p>Everyone has their limits on what they will tolerate in exchange for a free service, which is why you see so many angry responses to terms of service that push the boundaries. Unfortunately, over time all our boundaries are slowly being pushed further and further out. Had FaceBook&#8217;s TOS been what it is today on their first day, people would just not have joined, but like a frog in boiling water we have all been slowly ground down and we accept more and more without a fight.</p>
<p>I absolutely do not like the future we are heading towards. By exploiting our collective greed and dangling free stuff in front of our faces corporations have managed to entice our society into giving up our privacy in ways even totalitarian governments have failed to do. The Stasi would have killed for Google&#8217;s database!</p>
<p>It just does not have to be this way!</p>
<p>Some people will insist on not paying for things, and many services, particularly social networks, require a critical mass of people to become useful, so free can&#8217;t go away. However, it can co-exist with paid services. The simplest way to do this is with a so-called &#8216;freemium&#8217; model. Your free users get sold to advertisers, while your paying users do not, and perhaps also get a more feature-rich service. This is how both Flickr and Instapaper work, and I&#8217;m a happy user of both services.</p>
<p>I&#8217;ve always hoped Twitter would go the freemium route. Imagine a world where you could pay a few Euro a month for a pro Twitter account which would enable the use of 3rd party apps free of silly limitations. The reason Twitter are hell-bent on destroying the 3rd party apps that made their service a success is that they need control of the user experience so they can sell their users to advertisers. Why not let the users who want apps pay for the use of the service instead!?</p>
<p>Another very interesting development is App.net, this is a completely paid social network. There are no free App.net accounts, which makes it an exceptionally brave move on their part. I&#8217;m really hoping it takes off and proves that there are alternatives to free, even in the social networking space. Because App.net was a paid service from day 1 they did not anger anyone by having to transition from a free loss-maker to a paid profit maker.</p>
<p>I say it&#8217;s time to stand up and demand to be allowed to pay for services. Each time someone puts up the straw-man that we HAVE to give up our privacy and intellectual property because a service is free, knock it down with the simple alternative that we be allowed pay for the service.</p>
<p>Let us become customers, I&#8217;m fed up of being the product!</p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2383</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>www.xkpasswd.net Updated</title>
		<link>http://www.bartbusschots.ie/blog/?p=2375</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2375#comments</comments>
		<pubDate>Mon, 06 Aug 2012 15:46:02 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2375</guid>
		<description><![CDATA[This afternoon I updated www.xkpasswd.net to version 0.2.1 of the XKpasswd.pm Perl module, and added the needed UI to expose some of the new features introduced in version 0.2.* of the module: It is now possible not to use any separator between the words that form the basis of your randomly generated password The padding [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/banner_xkpasswd.png" alt="www.xkpasswd - A Secure Memorable Password Generator" title="banner_xkpasswd.png"  width="225" height="60" style="float:right;margin:3px;border-width:0px" />This afternoon I updated <a href="https://www.xkpasswd.net/" target="_blank">www.xkpasswd.net</a> to version 0.2.1 of the <a href="http://www.bartb.ie/xkpasswd">XKpasswd.pm</a> Perl module, and added the needed UI to expose some of the new features introduced in version 0.2.* of the module:</p>
<ol>
<li>It is now possible not to use any separator between the words that form the basis of your randomly generated password</li>
<li>The padding character can now be set to be randomly chosen, independently of the separator character. This is now the default setting, and provides more entropy by default.</li>
<li>An additional care transform has been added, you can now choose to have the capitalisation alternate on each subsequent word.</li>
</ol>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2375</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Announcing XKpasswd.pm Version 0.2.1</title>
		<link>http://www.bartbusschots.ie/blog/?p=2367</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2367#comments</comments>
		<pubDate>Mon, 06 Aug 2012 15:32:45 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux, GNU & FOSS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2367</guid>
		<description><![CDATA[This is a minor bug-fix update for XKpasswd (my Perl random password generation module). It squashes two minor bugs which came to light while updating www.xkpasswd.net to use version 2 of the module. When the custom_separator option was left blank, no separator was used, rather than the expected random separator. When the custom_separator option was [...]]]></description>
				<content:encoded><![CDATA[<p>This is a minor bug-fix update for <a href="http://www.bartb.ie/xkpasswd">XKpasswd</a> (my Perl random password generation module). It squashes two minor bugs which came to light while updating <a href="https://www.xkpasswd.net/" target="_blank">www.xkpasswd.net</a> to use version 2 of the module.</p>
<ol>
<li>When the <code>custom_separator</code> option was left blank, no separator was used, rather than the expected random separator.</li>
<li>When the <code>custom_separator</code> option was left blank or set to <code>RANDOM</code>, and the <code>pad_char</code> option to <code>SEPARATOR</code>, the results were un-expected,  different random character was used for each, rather than the same random character.</li>
</ol>
<p>For documentation and detailed release notes on version 2 of the module, see the <a href="http://www.bartbusschots.ie/blog/?p=2329">release notes for version 2.0</a>.</p>
<p style="text-align:center"><a href="http://www.bartb.ie/downloads/xkpasswd-v0.2.1.zip"><img alt="Download" src="/downloads/download.png" style="border:0px solid black" /></a></p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2367</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Making an XKpasswd Automator Action</title>
		<link>http://www.bartbusschots.ie/blog/?p=2357</link>
		<comments>http://www.bartbusschots.ie/blog/?p=2357#comments</comments>
		<pubDate>Sat, 04 Aug 2012 16:33:53 +0000</pubDate>
		<dc:creator>Bart Busschots</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Linux, GNU & FOSS]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Automator]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[xkpasswd]]></category>

		<guid isPermaLink="false">http://www.bartbusschots.ie/blog/?p=2357</guid>
		<description><![CDATA[A few weeks ago on the Chit Chat Across the Pond segment of the Nosillacast, I mentioned that I had an OS X service set up to generate a random password using my XKpasswd Perl module and copy it to the clipboard. Listeners enquired as to how they would go about doing that, so as [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/XKpasswdAutomator.png" alt="Automator + XKpasswd" title="XKpasswdAutomator.png"  width="226" height="304" style="float:right;margin:3px;border-width:0px" />A few weeks ago on the Chit Chat Across the Pond segment of the <a href="http://www.podfeet.com/" target="_blank">Nosillacast</a>, I mentioned that I had an OS X service set up to generate a random password using my <a href="http://www.bartb.ie/xkpasswd" target="_blank">XKpasswd Perl module</a> and copy it to the clipboard. Listeners enquired as to how they would go about doing that, so as promised, here&#8217;s a quick tutorial.</p>
<p>Obviously this tutorial is for Mac OS X users only, because OS-wide Services and Automator are OS X features. The screenshots are taken on 10.8 Mountain Lion, but this same technique definitely also works on OSX 10.7 Lion, and probably even on 10.6 Snow Leopard. This tutorial also assumes that you have downloaded the <code>XKpasswd</code> module, and saved it somewhere on your computer, along with either the sample dictionary file included with the module or one of your own making, and that you know where on your computer those files have been saved. In other words, you need to have <code>XKpasswd.pm</code> and a text file with one word per line somewhere on your hard drive. In my sample code I&#8217;m going to assume you&#8217;ve installed the Perl module to the suggested location, <code>/usr/local/xkpasswd/XKpasswd.pm</code>, and that you have customised the sample dictionary a little (more secure that way), and saved it to <code>/usr/local/xkpasswd/dict.txt</code>.</p>
<p><br clear="all" /><span id="more-2357"></span>
<p>Lets get started by opening up the Automator app (<code>Applications→Automator</code>), and creating a new file. Automator will ask you what type of document you want to create, choose <code>Service</code>.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-14.56.24.png" alt="Create a new Document of Type Service" style="border-width:0px;" width="490" height="470" /></p>
<p>At the top of this new blank document there are some options which control the input the service will expect, and which apps the service will be available in. Since we are generating the password from scratch, there is no input required at all, and we want this service to be available everywhere, so set the <code>Service receives</code> drop-down to <code>no input</code>, and leave the <code>in</code> drop down at the default <code>any application</code> as shown below:</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-15.02.06.png" alt="Service received no input in any application" style="border-width:0px;" width="490" height="144" /></p>
<p>Next we need to add a <code>Run Shell Script</code> action to the service. The easiest way to find this action in the list of actions is to type &#8216;run&#8217; in the search box. When you find it, drag and drop it into the service.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-15.04.49.png" alt="Add a Run Shell Script action to the service" style="border-width:0px;" width="490" height="469" /></p>
<p>In this new action, we need to change the <code>Shell</code> from the default value <code>/bin/bash</code>, to <code>/usr/bin/perl</code>, and then delete the default code that is added to the text box. We will be starting with a blank slate. (Since we are taking no input, we can ignore the <code>Pass Input</code> drop down completely this time.) By Default the text box in the action is very small, so you&#8217;ll probably want to enlarge it by grabbing the &#8216;handle&#8217; on the bottom right corner and dragging it down a bit. Better still, you could open a programming editor like the fantastic and cheap <a href="http://www.peterborgapps.com/smultron/" target="_blank">Smultron</a>,  write your code there, and then copy and paste it back into automator when you&#8217;re done.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-15.11.00.png" alt="Set the Shell to Perl and delete the sample code" style="border-width:0px;" width="490" height="233" /></p>
<p>Now we have to write the Perl code. I&#8217;m going to follow my own advice and use Smultron. Why? Because that way I get syntax highlighting which makes typos much easier to spot. It will also make the script easier to debug if you&#8217;re having problems, by making it easy to run the Perl code in the Terminal. If you don&#8217;t have Smultron or a similar coding editor, you can use TextEdit <strong>provided you use it in Plain Text mode</strong> (<code>Format->Make Plain Text</code>).</p>
<p>In Smultron (or TextEdit), start by creating a new document, and saving it somewhere on your hard drive with the extension <code>.pl</code>, I&#8217;m going to call my script <code>xkpasswdService.pl</code> and save it in <code>~/Documents/temp</code>.</p>
<p>We&#8217;re now ready to start writing some Perl code. If you&#8217;ve never programmed before, don&#8217;t worry, but pay very close attention, programming is a precise art, <code>'</code>, <code>"</code>, and <code>`</code> are different symbols with different meanings, and capitalisation matters, <code>And</code> is not the same as <code>and</code>, and so on. You&#8217;re probably best off copying and and pasting the final code further down in this article and then tweaking it for your needs, rather than trying to write it all yourself from scratch. Alternatively, I&#8217;ve included the code a file called <code>xkpasswdService.pl</code> in the downloadable ZIP archive linked near the bottom of the article. Although I want you to copy and paste the code (from either this article or the file in the archive), I&#8217;m going to build up the code piece by pice so I can explain each section clearly.</p>
<p>Lets start the script with some good practice. If you learn nothing more about Perl today than these first two lines, you&#8217;ll have learned a lot. You CAN write Perl without them, but you&#8217;re just making life harder for yourself, especially as your scripts get larger and more complex. Think about writing Perl without <code>strict</code> and <code>warnings</code> as being like tightrope walking without a safety net &#8211; best avoided <img src='http://www.bartbusschots.ie/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div id="ig-sh-2" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Next, we need to include the <code>XKpasswd</code> module. This is not a part of standard Perl, so we first need to tell Perl which folder the <code>.pm</code> file is in, only then we can include it. To tell Perl where to look, we use the <code>use lib</code> directive, and to actually use the module, we use the <code>use</code> directive. If you&#8217;ve installed <code>XKpasswd.pm</code> in a location other than <code>/usr/local/xkpasswd/</code> you&#8217;ll need to adjust this line accordingly.</p>
<div id="ig-sh-3" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> lib <span style="color: #ff0000;">'/usr/local/xkpasswd'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> XKpasswd<span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>The next step is to build up a variable with the configuration details to be used by the <code>XKpasswd</code> module while generating passwords. We&#8217;re going to use a type of variable called a <em>hashref</em>, and we&#8217;re going to call it <code>$xkpasswd_config</code> (in Perl all &#8216;scalar&#8217; variable names begin with a <code>$</code> symbol). A hashref is simply a good data structure for storing and passing around key-value pairs in Perl. In the case, the keys will the configuration options we would like the module to use when generating the passwords. I&#8217;m going to build up this variable in steps, but you don&#8217;t have to do that, you could do it all in one go. The reason I&#8217;m doing it in steps is to split the options that are compulsory from the ones that are optional. It&#8217;s important to note at this stage that in Perl, any line beginning with a <code>#</code> symbol is ignored by the Perl interpreter, and so does not make up part of the program. These lines are called <em>comments</em>, and are there purely for the benefit of humans, they are there to help us understand what the code is doing.</p>
<p style="font-style:italic"><strong>Aside</strong> &#8211; there&#8217;s an old programming joke that code comments are like sex, even bad comments are better than none at all <img src='http://www.bartbusschots.ie/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<div id="ig-sh-4" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># build up the config for the XKpasswd object,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># starting with the required fields</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$xkpasswd_config</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; dictionary_file <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'/usr/local/xkpasswd/dict.txt'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; min_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; max_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>The <code>dictionary_file</code> option specifies the location of the dictionary file the XKpasswd module should use when generating the passwords. If you&#8217;ve saved your dictionary file somewhere else, you&#8217;ll have to adjust this line accordingly. The <code>min_word_length</code> and <code>max_word_length</code> options specify the minimum and maximum length of the words from the specified dictionary that should be used when building the password. The way it works is that the dictionary is read in once, and all words not within the range specified by these two values (inclusively) will be ignored and not loaded by the module. Also note that the module will throw an error if it does not load at least 1000 matching words from your dictionary file (this is to ensure your random passwords really are random, or, in nerd speak, that they have sufficient entropy).</p>
<p>Next we start adding any further optional options we desire. All these options can be left out, and the module will just use default values for you. I&#8217;m only going to show some of the commonly used ones here, for a full list of supported options see the extensive comment starting at line 36 of <code>XKpasswd.pm</code>, or the sample file (<code>example.pl</code>) distributed with the module.</p>
<p>First, lets decide how many words we&#8217;d like our password to be built from, and what, if any, case transformations we&#8217;d like to see applied to those words. The valid values for the case transformation are <code>NONE</code> (leave the words as they appear in the dictionary file), <code>CAPITAL</code> (capitalises the first letter of every word), <code>UPPER</code> (convert all words to entirely upper case), <code>LOWER</code> (convert all words to entirely lower case), <code>ALTERNATE</code> (convert each alternate word to all upper case, then all lower case, then all upper case and so on), and finally, <code>RANDOM</code> (randomly convert each word to all upper or all lower case). If the option is not specified at all, the module defaults to applying no case transformations. Note that we must surround the value in the capitalisation variable with so-called <em>single quote</em> symbols.</p>
<div id="ig-sh-5" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># choose how many words to use, and</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># how they should be capitalised</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>num_words<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>case_transform<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'CAPITAL'</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Second, lets decide what character we will use to separate the words that will make up the bulk of the generated passwords. We can specify a single character, or, the special values <code>RANDOM</code>, for a randomly chosen character each time a password is generated, or <code>NONE</code> if we don&#8217;t want any separator character to be used. BTW &#8211; if this option is not specified, the module defaults to using a random character. In this case I&#8217;m going to use the character <code>+</code>. Note that, again, we have to surround the value for the separator option with <em>single quote</em> characters.</p>
<div id="ig-sh-6" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># specify the character to use to separate</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># the parts of the password</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>custom_separator<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'+'</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Thirdly, lets specify how many random digits to include before and after the words that make up our password. The numbers before and after don&#8217;t have to be the same, and if you don&#8217;t want any digits, you can set the values to <code>0</code>. I&#8217;m going to add no random digits before the words, and three after. The default is three before and three after.</p>
<div id="ig-sh-7" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># specify the number of random digits to add</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># before and after the words in the password</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>prepend_numbers<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>append_numbers<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Finally, lets configure the padding of the password. The <code>XKpasswd</code> module can pad out your password to a bigger size by adding one or more symbols before and/or after the words and digits that make up your password. By default a random symbol is chosen, and three copies of that symbol are added to the front and back of the password. In this example lets change that behaviour to using 5 exclamation marks at the beginning and the end of our passwords.</p>
<div id="ig-sh-8" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># specfify how the password should be padded</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>pad_char<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'!'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>pre_pad<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>post_pad<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Putting it all together, at this stage our code should look like this:</p>
<div id="ig-sh-9" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> lib <span style="color: #ff0000;">'/usr/local/xkpasswd'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> XKpasswd<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># build up the config for the XKpasswd object,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># starting with the required fields</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$xkpasswd_config</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; dictionary_file <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'/usr/local/xkpasswd/dict.txt'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; min_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; max_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># choose how many words to use, and</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># how they should be capitalised</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>num_words<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>case_transform<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'CAPITAL'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># specify the character to use to separate</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># the parts of the password</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>custom_separator<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'+'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># specify the number of random digits to add</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># before and after the words in the password</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>prepend_numbers<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>append_numbers<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># specfify how the password should be padded</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>pad_char<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'!'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>pre_pad<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>post_pad<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>However, we could compress it a little by making all the declarations in one go. This will make the code shorter, but the details comments will have to be sacrificed. It won&#8217;t make any functional difference to how the code works though, so you can leave it as-is if you prefer. I&#8217;m going to shorten it a little, because I find that easier to read and edit.</p>
<div id="ig-sh-10" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> lib <span style="color: #ff0000;">'/usr/local/xkpasswd'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> XKpasswd<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># build up the config for the XKpasswd object,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># starting with the required fields</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$xkpasswd_config</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; dictionary_file <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'/usr/local/xkpasswd/dict.txt'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; min_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; max_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; num_words <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; case_transform <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'CAPITAL'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; custom_separator <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'+'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; prepend_numbers <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; append_numbers <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; pad_char <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'!'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; pre_pad <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; post_pad <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>We are now ready to create an <code>XKpasswd</code> object, which can then be used to generate passwords as specified by the config we&#8217;ve assembled.</p>
<div id="ig-sh-11" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># instantiate an XKpasswd object with the above config</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$xkpasswd</span> <span style="color: #339933;">=</span> XKpasswd<span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Finally, with the object created, we can generate a password, and print it. The way the Run Shell Script Automator Action works is that what ever the script prints out is used as the output of the action and passed on as the input to the next Action in the workflow. Note that we are using the word print in a software sense, not a hardware sense. We&#8217;re talking about printing to the <em>standard output stream</em>, not a piece of paper.</p>
<div id="ig-sh-12" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># generate a random password and print it</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000066;">print</span> <span style="color: #0000ff;">$xkpasswd</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">generate_password</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Our final assembled code now looks like this:</p>
<div id="ig-sh-13" class="syntax_hilite">	<div class="toolbar">		<div class="language-name">perl</div>		<a href="#" class="view-different">&lt; view <span>plain text</span> &gt;</a>	</div>	<div class="code"><ol class="perl" style="font-family:monospace;"><li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> lib <span style="color: #ff0000;">'/usr/local/xkpasswd'</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000000; font-weight: bold;">use</span> XKpasswd<span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># build up the config for the XKpasswd object,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># starting with the required fields</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$xkpasswd_config</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; dictionary_file <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'/usr/local/xkpasswd/dict.txt'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; min_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; max_word_length <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; num_words <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; case_transform <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'CAPITAL'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; custom_separator <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'+'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; prepend_numbers <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; append_numbers <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; pad_char <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'!'</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; pre_pad <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp; &nbsp; post_pad <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">,</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># instantiate an XKpasswd object with the config we built</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$xkpasswd</span> <span style="color: #339933;">=</span> XKpasswd<span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$xkpasswd_config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;">&nbsp;</div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #666666; font-style: italic;"># generate a random password and print it</span></div></li>
<li style="font-weight: normal; vertical-align:top;"><div style="font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;"><span style="color: #000066;">print</span> <span style="color: #0000ff;">$xkpasswd</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">generate_password</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></li>
</ol>	</div></div>
<p>Before copying and pasting this code into the <code>Run Shell Script</code> Action back in Automator, we should test it. To do that we&#8217;re going to make use of the so-called <em>proxy icons</em> (the little icons next to the file name in the window&#8217;s title bar) native OS X documenting editing apps like TextEdit and Smultron provide. Before trying to test your code, be sure to save your document! Start by opening a terminal window (<code>Applications→Utilities→Terminal</code>) and typing the word <code>perl</code> with a single space after it (DO NOT HIT ENTER YET) into the Terminal window. Then, drag and drop the proxy icon at the top of your TextEdit/Smultron window onto your Terminal window, this should copy the full path to your Perl script into the Terminal.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-17.00.31.png" alt="Drag and Drop the Proxy Icon onto the Terminal Window" style="border-width:0px;" width="473" height="600" /></p>
<p>Once the path is in your Terminal window, you can go ahead and hit enter. If there are no errors in your code, a random password should be printed, and then you should get a fresh prompt directly after it on the same line (this is because we are not including a newline character when printing the password to keep automator happy). It should look something like this (I&#8217;ve underlined the password in red):</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-17.09.16.png" alt="Test the Script in the Terminal" style="border-width:0px;" width="490" height="355" /></p>
<p>The two most likely errors you might encounter would be caused by getting one of the two paths wrong. If you get the include path for the <code>XKpasswd</code> module wrong you&#8217;ll see an error starting with <code>Can't locate XKpasswd.pm in @INC</code> (I&#8217;ve underlined the important part of the error in the screenshot below).</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-17.12.35.png" alt="Wrong Include Path" style="border-width:0px;" width="490" height="355" /></p>
<p>If, on the other hand, you made a mistake with the path to the dictionary file you&#8217;ll see an error that starts with <code>Required config option dictionary_file is invalid</code> (again, I&#8217;ve underlined the important part of the error in the screenshot below).</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-17.16.511.png" alt="Invalid Dictionary Path" style="border-width:0px;" width="490" height="355" /></p>
<p style="font-style:italic"><strong>Aside</strong> &#8211; if you didn&#8217;t know about proxy icons, they&#8217;re one of OS X&#8217;s coolest power features &#8211; want to email someone a document you have open, just drag and drop the proxy icon onto the mail.app icon in your dock, want to go to a folder you have open in the Finder in the Terminal, just type <code>cd</code> followed by a space into the Terminal window, drag and drop the proxy icon from the Finder window onto the Terminal window, and hit enter, want to copy a document you have open to a thumb drive, just drag and drop the proxy icon onto the icon for the thumb drive on the desktop, or onto a Finder window showing the contents of the thumb drive etc..</p>
<p>When you&#8217;re happy that the script is working, you can copy and paste the code into the <code>Run Shell Script</code> Action back in Automator.</p>
<p>Next we need to add an Automator Action into our workflow to copy the value passed to it into the clipboard. Unsurprisingly, this action is called <code>Copy to Clipboard</code>. Again, the easiest way to find it is to search for it, and when you have found it you need to drag and drop it into your workflow <strong>below</strong> the <code>Run Shell Script</code>.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-17.23.16.png" alt="Drag and Drop in a Copy to Clipboard Action" style="border-width:0px;" width="447" height="490" /></p>
<p>At this stage your action should look something like the screenshot below, and you can test it by clicking on the <code>Run</code> button in the toolbar on the top right of the Automator window. You can see the contents being returned by each action if you click the <code>Results</code> button on the bottom of the Actions. If all is well, a green tick should show next to each Action. If there&#8217;s an error, the details will be in the log, which will appear at the bottom of the window.</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-17.27.48.png" alt="Test the Service" style="border-width:0px;" width="372" height="490" /></p>
<p>At this stage, you can save the Service, and start using it. However, I like to add an action to show a Growl notification when the password is ready. Particularly the first time you use a Service, it can take a few seconds to load and run, so it&#8217;s very handy to see some form of visual feedback when the password is ready for you in the clipboard. Obviously this will only work if you have Growl installed on your Mac. Sadly, as of OS X 10.8.0 there is no Automator action to send a message to the new Notification Centre in OS X Mountain Lion, which strikes me as an annoying oversight by Apple.</p>
<p>The downloadable ZIP below contains two copies of the service, one with Growl, and one without. To install them, just copy them to your <code>~/Library/Services</code> folder. If you&#8217;re using Lion or Mountain Lion you can get to your Library folder by holding down the Option key when you click the <code>Go</code> menu in the Finder, and then selecting the <code>Library</code> option which appears.</p>
<p style="text-align:center"><a href="http://www.bartb.ie/downloads/xkpasswd-v0.2-AutomatorActions.zip"><img alt="Download" src="/downloads/download.png" style="border:0px solid black" /></a></p>
<p>Finally, if you&#8217;d like to add a keyboard shortcut for your new Service, you can do this using the <code>Keyboard Shortcuts</code> tab in the <code>Keyboard</code> applet in <code>System Preferences</code>. In here you&#8217;ll need to select <code>Services</code> in the left panel, and then scroll until you find your new <code>XKpasswd</code> service listed (probably at the bottom) in the right pane, select it, click the <code>add shortcut</code> button that appears, and then enter your chosen shortcut (I use <code>ctrl+x</code>).</p>
<p style="text-align:center"><img src="http://www.bartbusschots.ie/blog/wp-content/uploads/2012/08/Screen-Shot-2012-08-04-at-16.52.29.png" alt="Add a keyboard shortcut" style="border-width:0px;" width="490" height="449" /></p>
	<p></p>]]></content:encoded>
			<wfw:commentRss>http://www.bartbusschots.ie/blog/?feed=rss2&#038;p=2357</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
