Headlines | Linux | Apps | Coding | BSD | Admin | News
Information for Linux System Administration 

Beginner Ubuntu Tips


Twenty-five tips for Ubuntu beginners...
Adding another source for software is easy; once you've installed addrepo, you can do it in the terminal by typing something along the lines of addrepo deb lucid-seveas all.

If you find new repositories online, they will usually give you the right details to enter. You could also do it graphically by going to 'System | Administration | Software Sources | Third Party Software | Add'. read more...
permapage | score:9323 | -Ray, November 9, 2010

Top BSD distributions


Here are the top five BSD's...
As some of you may know, Linux is not the only Unix-like operating system available. There are other UNIX derivatives, and one of the most popular among them is called BSD. If you have been to Distrowatch, you will see different BSD distributions listed in there.
permapage | score:9309 | -Ray, April 5, 2009

Linux network tools: iptstate and pkstat


Two small Linux tools for network stats...
iptstate displays information held in the IP Tables state table in real-time in a top-like format. Output can be sorted by any field, or any field reversed. Users can choose to have the output only print once and exit, rather than the top-like system.

Refresh rate is configurable, IPs can be resolved to names, output can be formatted, the display can be filtered, and color coding are among some of the many features.
(here are some red prints)
mail this link | permapage | score:9306 | -Ray, March 4, 2011 (Updated: April 24, 2012)

Benchmarks: FreeBSD 8.0 vs. Solaris vs. Linux


FreeBSD 8.0 takes on Fedora 12 and Ubuntu 9.10 as well as OpenSolaris 2010.02 b127 in a performance free-for-all..
The hardware we are using for benchmarking this time was a Lenovo ThinkPad T61 notebook with an Intel Core 2 Duo T9300 processor, 2GB of system memory, a 100GB Hitachi HTS72201 7200RPM SATA HDD, and a NVIDIA Quadro NVS 140M graphics processor powering a 1680 x 1050 LVDS panel.
permapage | score:9302 | -Ray, December 1, 2009

The best lightweight Linux


A subjective assessment of several leading small-footprint Linux distributions...
In selecting our shortlist, we've left out some contenders either because they didn't support older processors, they wouldn't install in 4GB or less of space, they simply didn't work on our hardware or they're no longer being maintained (as is the case for both RULE and U-Lite). The one exception to this is Damn Small Linux - although it has been over a year since the last release, and the homepage is as quiet as the LXF office at 9.30 on a Monday morning, this is still such a widely used and influential project that it was considered worthy of inclusion.
mail this link | permapage | score:9284 | -Ray, April 11, 2010

Space Tyrant Index Page: Linux game server development project


This page links to the various articles that have been published about Space Tyrant, a multithreaded, network socket programming Linux game server project in C.

[Update: 07Jun2014 You can play a development version of an upcoming MMORPG in text mode at telnet://
or, on a command line, enter:
telnet 2323
to log in and play. This game is based on Space Tyrant and the scenario is based on a modified Starship Traders.]

[Update: 03Jun2014 Starshiptraders, the parent of Space Tyrant, and the descendant of Czarwars, Lives Again]

Read below for the history and overview or just click these links for the articles:Space Tyrant is a C language Linux game server development project. It started out in February, 2005 as a humble echo server with high ambitions. On March 18, ST had its design and intentions announced to the world.
Today we kick off a new multithreaded, network socket programming project which we will call Space Tyrant. Our mission is to write an open source, multiplayer, networked, strategy game in the C programming language. The goal of this project is to make a solid code base which implements a simple space trading game upon which other games can then be built. The game will be a subset of The Last Resort (TLR) that currently runs at This project will be a learning exercise for me as well as for any interested readers. The current state of the source code will be released with each article update.
Source code to ST, then just an echo server, was not released.

Then, on March 27, 2005, ST was promoted to a crude chatserver.
This is the first code release of Space Tyrant. This is an early stage of development and, at this point, only implements the listening thread, the two IO threads for each player connection, and a skeletal game logic thread that does little beyond proof-of-concept code.
Next, on May 30, 2005, ST started to resemble some sort of incomplete text game.
It’s now possible to connect to the game via telnet and to create an account, log in, and be issued a ship. Once you’re logged in, there is a universe to explore filled with ports for buying and selling goods and planets for scooping free goods. From those trading activities you can earn money, called microbots. Other than trading to earn more money, you only use your microbots to buy fighters -- which you can use to attack other players or the neutral fighters that guard some sectors.
As of this release, the source code was placed under the GPL, version 2.

On June 26, 2005, Space Tyrant was released with many shiny new abilities. Players can now deploy fighters to guard sectors, navigate with the aid of an autopilot, rank the various players in the universe, and sleep peacefully knowing their alternate universe is being backed up constantly by a sporty new backup thread. Yes, good times are surely upon us.
If you’re looking for a planet, type the ‘L’ command that you would normally use to land on a planet in your sector. In the absence of a planet, the L key will engage the autopilot which will search for the nearest planet and give you a ‘/’ command to autowarp to it.
There is normally a copy of the development version of the server running on my decTOP on port 23. To access it, type (or click, if it works for you) the following command:

(telnet to my ST server)

The current development version of the code is usually at but the individual articles link to the specific versions discussed in each article.

You can mail me about the project at spacetyrant [at] -- or you can just telnet into Space Tyrant, as listed above, and send me a radio message. I'm likely to get that faster. ;)

The Space Tyrant project has a new website,, where the latest source code is always available. Also, new articles about ST programming and about ST gameplay will be posted there as they come available.

Information on The Last Resort follows. TLR is one of the two games that Space Tyrant is intended to replace someday. Space Tyrant has a long way to go before it replicates TLR's 25,000 lines of C code. So far, it has reused only about 40 lines of TLR code, a handy 'bit-plane' sort dating back to 1998.

  • TLR Survival Manual
  • Is this game for you?
  • mail this link | permapage | score:9279 | -Ray, June 25, 2005 (Updated: June 7, 2014)

    Python for Kids


    A series of Python tutorials for children (or programming newbies) in a blog format. The article linked below implements a stand-alone Python program.
    In the last tutorial we created a file using our text editor and saved a function to it. This file was called and in it was the module “trivia”. We then started Python in a console and import()ed the trivia module. Once imported, it created a “namespace” and we could access the askQuestion() function from within the trivia namespace by using a dot – trivia.askQuestion(). In order for the module to work properly we had to include an import statement within the module itself so that everything that the module relied upon was imported within the module. We then manually loaded our data from a pickle file we created and, manually, ran the askQuestion() function on the first question in our data store. Finally we added docstrings to the function and the module.

    In this tutorial we’re going to try to do much the same thing again, but without using the Python interpreter. That is, we will need to take the things we did in the interpreter and implement them in our file. We will have a functioning (although still quite simple) stand alone Python program.
    mail this link | permapage | score:9275 | -Ray, May 19, 2011

    Tutorial: UDP socket based client server C programs


    This short and sweet tutorial has the example C source code for both a UDP client and server.
    This article explains how to write a simple UDP client/server system in C for the Linux or Unix platform. Writing client-server applications using UDP sockets is considered very easy, yet we sometimes miss some essential steps, which results in spending more time in intense debugging sessions. I went through one such experience. It is quite hard to remember all the socket API details quickly without having to wade through tons of man pages, so this page lists the standard code for UDP Client Server program. I hope it will be useful for others, too.
    [The original article has gone offline and the link has been replaced by a working page. -Ed.] read more...
    mail this link | permapage | score:9238 | -Ray, February 23, 2004 (Updated: August 24, 2008)

    Ubuntu 11.04 Preview


    An early look at the next release of Ubuntu Linux...
    Ubuntu 11.04 (Natty Narwhal) Beta 1 is powered by Linux kernel 2.6.38, GNOME 2.32.1 and X.Org 7.5. It will included applications such as LibreOffice 3.3.2 as the default office suite, Banshee 1.9.4 as the default audio player/organizer and Mozilla Firefox 4.0 as the default web browser.

    A set of seventeen new and beautiful wallpapers will also be present in the Beta release, to please every Ubuntu user out there. And now, the features we've promised...
    mail this link | permapage | score:9234 | -Ray, April 1, 2011

    Currency Traders on Raspberry Pi


    You can now run Currency Traders on your Raspberry Pi. It is extremely efficient and takes only about 2.2% of the memory of a 512MB RPi and less than 0.5% of the CPU. More CPU will be consumed when players are online, of course, but it should support up to a hundred or so concurrent players on a normally clocked Pi.

    The installation is four quick steps, described in the readme.txt file. The entire system is a single binary, available either dynamically linked or statically linked. The static version should work on most any Pi running most any Linux. The dynamically-linked version was compiled and tested on Raspbian Wheezy and may work without library fiddling on other Pi Linuxes. [links removed]
    mail this link | permapage | score:9231 | -Ray, March 3, 2013 (Updated: May 13, 2014)

    perl1line.txt: A handy Perl script collection


    The ultimate goal of the Perl One-Liners Explained article series was to release the perl1line.txt file. Last week I finished the series and now I am happy to announce perl1line.txt - a collection of handy Perl one-liner scripts.

    The perl1line.txt file contains over a hundred short Perl one-line scripts for various text processing tasks. The file processing tasks include: changing file spacing, numbering lines, doing calculations, creating strings and arrays, converting and substituting text, selective printing and deleting of certain lines and text filtering and modifications through regular expressions.

    The latest version of perl1line.txt is always at:
    Enjoy! It took me over 3 years to write all the one-liners down. read more...
    mail this link | permapage | score:9221 | -pkrumins, November 21, 2011

    Tutorial: Linux Dialog Boxes


    Dialog lets you create dialog boxes from Unix/Linux shell scripts...
    'dialog' is a utility for building console-based 'front ends' in UNIX like operating systems.

    In this brief tutorial I am mentioning the usage of few important basic controls available with this 'dialog' utility and later I have created a very simple front end application in UNIX bash scripting using dialog.
    permapage | score:9206 | -Ray, January 1, 2010

    How to install Ubuntu Linux on the decTOP SFF computer


    I recently bought a decTOP small form factor (SFF) computer. My goal was to build a cheap, fanless, quiet, and low power consumption Linux server. For $99 plus the cheapest available shipping, $40, my machine arrived 11 days after I placed the order.

    This is a tiny computer, about the size of a Mac Mini. But, because it has no fan, it runs a bit quieter and, with the help of a 1-watt, 366 MHz CPU, consumes only 8 watts. For comparison, the G4 Mac Mini consumes about 20-30 watts, depending on load.

    The decTOP comes with 128 MB of RAM in its sole SO-DIMM slot and a 10 GB 3.5 inch hard drive. I understand that it's a simple matter to replace the drive and to upgrade the memory to a maximum of 512MB.

    It also comes with no operating system and the ability to boot only from a USB drive. This article details the steps I used to build the USB boot/installation drive and install Ubuntu 6.06 on the decTOP.

    There is another article -- with additional decTOP links -- here on installing Ubuntu 6.06 on the decTOP with the aid of a Windows system. Fortunately ;), I run Mac OS X and Linux (Ubuntu 7.04), so that article didn't work for me. I did the installation of the Ubuntu 6.06 LTS Server Edition using my Ubuntu Linux box and a 1 GB USB flash drive -- although a 512 MB USB drive should work as well.

    1. Download the Ubuntu 6.06 server ISO image from the Ubuntu download page. Depending on your plans for the decTOP, you might want to choose the desktop version. Unless you have already upgraded your decTOP's memory, however, you'll want to stick with the 6.06 releases.

    2. Install the mbr, mtools, and syslinux packages on the Linux system you'll be using to prepare the USB drive. If you run Ubuntu or some other Debian-derived system, the following commands may do the work for you.
      apt-get install mbr
      apt-get install mtools
      apt-get install syslinux
    3. Partition the USB drive with a single FAT-16 partition. I used the fdisk 'n' command to make the new primary partition 1. The fdisk 't' command can be used to change the partition type to FAT-16. My device name was /dev/sda.
      fdisk /dev/sda
    4. Make the FAT-16 partition the active partition. I used the fdisk 'a' command.

    5. Install a master boot record on the USB drive.
      install-mbr /dev/sda
    6. Install syslinux on the USB drive. Note that the USB drive should not be mounted when you do this.
      syslinux -s /dev/sda1
    7. Create a mountpoint and mount the ubuntu ISO image using the loopback device.
      mkdir /iso
      mount -o loop -t iso9660 ubuntu.iso /iso
    8. Create a mountpoint and mount the USB flash drive.
      mkdir /usb
      mount /dev/sda1 /usb
    9. Copy the contents of the ISO image to the USB drive. This will take some time.
      cd /iso
      cp -r . /usb/
    10. Copy the /usb/dists/dapper directory into a new /usb/dists/stable directory.
      cd /usb/dists/
      cp -r dapper/* stable
    11. Copy several files from /usb/install to the /usb root directory.
      cp /usb/install/vmlinuz /usb/
      cp /usb/install/mt86plus /usb/
      cp /usb/install/initrd.gz /usb/
    12. Install the following text into a file named syslinux.cfg in the /usb root directory.
      default vmlinuz
      append initrd=initrd.gz ramdisk_size=24000 root=/dev/ram rw
    13. Flush all writes, unmount, and remove the USB drive. After the sync step, wait for all of the data to be written to the USB drive.
      umount /usb
    14. Connect the ethernet adapter to the decTOP and connect it to your network to allow automatic configuration of the network interface.

    15. Insert the USB drive into the decTOP and power it up. The decTOP should automatically boot from the USB drive and start the Ubuntu installation.

    16. Answer only the first two questions concerning language selection and go to the next step, below.

    17. Press Alt-F2 (hold down the Alt key and press the F2 function key) to open a shell. Then press enter to start the shell.

    18. Create a /cdrom and a /dev/cdroms directory in the installation ramdisk
      mkdir /cdrom /dev/cdroms
    19. Go to the /dev/cdroms directory and build a symlink from /dev/sda1 (that is likely the device name of your USB boot partition) to /dev/cdroms/cdrom0.
      cd /dev/cdroms
      ln -s ../sda1/cdrom0
    20. While still in the shell, mount the USB drive to mimic an installation CD-ROM.
      mount -t vfat /dev/cdroms/cdrom0 /cdrom
    21. Return to the installation program with Alt-F1 and continue the installation.

    From this point, the process should be identical to a routine CD-ROM installation.

    For a grand total of $140 and 8 watts of power consumption, I now have a near-silent Linux server running 24/7. You can telnet to it here and marvel at its blinding speed running a 250,000-sector Space Tyrant game.

    mail this link | permapage | score:9190 | -Ray, August 16, 2007 (Updated: April 26, 2011)

    Protect SSH from dictionary attacks with pam_abl


    Use pam_abl module to stop brute force attacks against your SSH server...
    Practically all Unix and Linux servers run an SSH service to let administrators connect securely from remote locations. Unfortunately for security administrators, attacks on SSH services are popular today. In this article I'll show you how can you protect machines running SSH services from brute force attacks using the pam_abl plugin for SSH pluggable authentication modules (PAM).
    permapage | score:9165 | -Ray, March 28, 2007

    Space Tyrant: Multithreading lessons learned on SMP hardware


    There is much to report in this update of Space Tyrant. Before getting into the new features and functions, I’ll dispense with the crisis of The Bug.

    For a couple of weeks, we had been noticing odd anomalies with Space Tyrant (ST) running on the virtual server at (now offline -Ed.). We never saw the problem on any other box -- and it was tested on at least four other Linux boxes and a Mac OS X system. We did all manner of stress testing, locally and over the Internet, script based and even feeding the game the output of /dev/random. Nothing caused the anomaly on any other box.

    At first, I suspected that it might just be an obscure problem with the virtual server itself; after all, I had been forced to modify the TLR code to get it to run properly there. That problem turned out to be merely a limitation of NFS, not a bug with the virtual server software. However, the environment was clearly different from any other system I had used which raised my suspicions -- and reduced my urgency about looking for the bug.

    While the bug wasn’t frequent, it was persistent. The bug appeared to be related to corrupted buffers or corrupted buffer indexes. Out of idle curiosity, I lowered the number of buffers used by ST to see if that affected the bug. Somewhat counter-intuitively, it substantially raised the frequency of the problem.

    Brian Estabrooks (the hero of this release) and I spent more and more of our efforts hunting this incredibly elusive bug until that was all we were doing. I implemented various diagnostic routines hunting for clues. The all seemed to point to buffer indexes being changed incorrectly. Both Brian and I audited the code. It seemed impossible for the indexes to be changed improperly. Brian even went so far as to replace the ring buffer scheme with a high watermark approach but to no avail.

    While I continued to suspect it to be a simple logic error in the code, Brian turned his efforts elsewhere. What he came up with was quite interesting. It seems that on many hardware architectures (most? all?), modifying a bit field can temporarily modify other bit fields in the same word! Now, this isn’t a problem on a single-CPU system; it repairs the damage in the same operation, making it, effectively, atomic. On an SMP machine, however, two different CPU’s working on different bit fields of the same word simultaneously create havoc. The operation isn’t really atomic and it doesn’t work.

    Did I mention that the virtual server is a 4-way Xeon system?

    The ring buffer indexing in ST relies on unsigned integer bit fields to automate wrapping back around to the first buffer after using the last one. My parsimonious programming, of course, packed all the bit fields together, several to a word. Brian’s test version of ST added a pad after each buffer index to round it out so that each bit field lived alone in its own complete word. We abused the new version for nearly an hour before either of us would dare say it. The bug was gone.


    So, the moral of this story is: Operations on sub-word fields affect other bits in that word (at least on many hardware architectures). Tread very carefully if multiple threads are accessing different bits in shared words. It may appear to work perfectly, only to crumble into a pile of smoldering rubble the first time it's loaded on a multiple CPU system!

    Other than the primary lesson, some other good things came out of (the search for) the bug. Several other latent bugs were found and fixed and Brian and I are both much more intimate with the code.

    And, on to the enhancements. ST is starting to look like an actual playable game. The following functions implement the new major features.

    players(): We now have player rankings. It works by adding all the players’ ship resources to an integer array. Then it scans the universe looking for deployed fighters and adds those to the array as well. Currently, those two items comprise the total strength of a player.

    It then sorts the array with a recursive bit-plane sort that I wrote for Starship Traders in 1998. The qsort() function in the C library was plenty fast, but took too much memory for my taste. Memory was a bit scarcer in those days and, worse, the SST software model gave each player his own copy of the server.

    The sort reorders the array in place as follows. It scans the high-order bit in each element of the array. It then moves all elements starting with ‘1’ bits to the top and all starting with ‘0’ bits to the bottom. Next, it calls itself twice to reorder the first and second chunks of the array on the second bit. Each of those two instances of the sort then call the sort twice again, now giving 4 new sorts for the third bit, and so on. When all 32 bits are accounted for, the array is in the correct order with the top player on top, etc.

    Scanning the entire universe can be expensive with a large map. Therefore, the player rankings function keeps the result and time stamps it. If another player asks for a player ranking within five seconds, the system just gives them the old one. After five seconds, however, any new request triggers a fresh listing.

    autopilot(): We’ve added an autopilot to let a player find a specific sector -- or to locate the nearest planet. If you type a ‘0’ (zero), you’ll be prompted for a sector number within 1000 of the sector you’re currently in. You then will have the option of pressing ‘/’ to automatically warp to the destination sector.

    If you’re looking for a planet, type the ‘L’ command that you would normally use to land on a planet in your sector. In the absence of a planet, the L key will engage the autopilot which will search for the nearest planet and give you a ‘/’ command to autowarp to it.

    The new autopilot function consists of two other functions in addition to autopilot(), which is merely a control function. I had intended to use the old shortest path algorithm function from TLR but it was big and complicated. I decided to try to write a simpler, recursive shortest path algorithm instead. The new recursive function is much simpler but not quite as efficient as the giant for loop in TLR.

    The actual algorithm is implemented in two functions called pathdepth() and pathcalc(). The pathdepth() function repeatedly calls pathcalc() with an increasing ‘depth’ parameter. ‘Depth’ tells pathcalc() how many levels deep to search before giving up.

    The pathcalc() function simply looks to see if the sector it is looking at is the target sector. If not, it calls itself for each new sector that the current sector connects to. If the current sector is the target sector, it starts filling in an array for the autowarp() function to follow to reach the target sector. As the previous recursive calls to the pathcalc() function exit, they fill in the remainder of the path array.

    And, yes, I seem to like reinventing the wheel. ;-)

    The other interesting addition to the code is the backup thread. It is implemented by a function called backupdata() and works as follows: It scans the player data, the map data, and the history data looking for ‘dirty’ flags. (Whenever any persistent data is changed anywhere in the game, a dirty flag is set to tell the backup thread to write it out to disk.) This process is quite fast for a small game, but for a game with millions of sectors, it’s a significant waste of resources to scan the dirty flag array frequently.

    Therefore, for the map and history data, I’ve implemented a ‘dirty block’ scheme as well. When a dirty flag is set, its corresponding dirty block flag is set too. Then, the backup thread need only scan the dirty block arrays, typically only about one percent the size of the arrays it represents. When a dirty block is found, only the hundred or so records it points to are scanned to find the actual dirty records for backup.

    The backup file, named ‘st.9999.dat’ -- where ‘9999’ varies with the port number you run the game on -- goes into the current working directory from where you start the daemon. If the file doesn’t exist, a new game is started. Also, if you’ve modified the game in a way that changes the size of the data -- by increasing the map size, for example -- it will start a new game upon startup.

    The game can be shut down from the command line by sending a signal 15 (kill -15 pid) or by the admin with the ^ command. Note that the first player to create an account in a new game automatically becomes the admin of the game!

    makehistory(): The storing of historical data is new as well. Whenever another player attacks your ship while you’re logged off, you’ll get a report of the action and any losses when you next log on. Also, for remote deployed fighters, you never get immediate notification, so that information is stored in the history log even if you're logged on when it happens. You can view any accumulated event information since your login time by pressing the ‘e’ key.

    deploy(): This simple function allows a player to deploy, or retrieve, guard fighters in a sector. Those fighters will not let another player pass through or view any of the contents of that sector. Any ships parked under the fighters are automatically protected against all attacks except for an attack by the fighters’ owner. Once the fighters are destroyed, of course, all ships there are visible and can be attacked.

    There is also a newly implemented time limit in the game to limit the total online time of a day’s sessions to 4 hours. Like most other parameters, it can be changed by modifying a #define statement near the top of the code.

    command(): The help page, a menu of available commands that a player can perform, has been redesigned and rewritten. This menu is attached to the '?' key.

    The old debugger thread is gone, replaced by an in-game command function called showdata(). Press the ‘z’ key to see information on buffers, buffer indexes, and the backup thread’s state and history. Only if you’re serious about modifying the code will this information be useful.

    The section of the gameloop thread that broadcasts radio and news messages has been modified to show only one of each type of message per pass. That way, replaying a long radio history won’t flood the output buffers and longer radio and news histories can therefore be retained.

    The old jumprtn() movement function has been consolidated into the warprtn() function. It’s only slightly more complicated than having them separate.

    The current source code can be downloaded from and the original article in this series is here. As usual, the compile script is embedded in the comments at the top of the source file. You’ll have to rename the source st.c for the script to work unchanged.

    [A Space Tyrant home page has been created as a central index to the various ST articles, links, and files.]
    mail this link | permapage | score:9156 | -Ray, June 26, 2005 (Updated: July 26, 2008)

    Trace network packet paths with traceroute


    An introduction and short guide to the traceroute networking utility...
    The tool traceroute is available in all Unix and Linux distributions and is used to find out the potential bottlenecks in between your computer and a remote computer across the net. The usage of this tool is quite simple and is as follows:
    permapage | score:9154 | -Ray, January 21, 2007

    Pattern matching in shell scripting


    This article is excerpted from the book Beginning Portable Shell Scripting.
    Shell programming is heavily dependent on string processing. The term string is used generically to refer to any sequence of characters; typical examples of strings might be a line of input or a single argument to a command. Users enter responses to prompts, file names are generated, and commands produce output. Recurring throughout this is the need to determine whether a given string conforms to a given pattern; this process is called pattern matching. The shell has a fair amount of built-in pattern matching functionality.
    mail this link | permapage | score:9145 | -Ray, January 1, 2009

    Solaris vs. Linux


    This two part article has part 1 here and part 2 here.
    As Linux encroaches on Solaris' turf, Solaris is doing some encroaching of its own. According to Bozman, businesses are starting to replace traditional mainframes, many of which are no longer sold actively, with Solaris-based machines.

    Bill Moffitt, Sun's group marketing manager for Solaris product management, told the E-Commerce Times that several regional banks have migrated from mainframes to Sun SPARC-based systems -- and that Sun is in the process of negotiating deals with several larger banks as well.
    mail this link | permapage | score:9131 | -Ray, September 17, 2003

    The Real Microsoft Monopoly


    The courts have ruled that Microsoft holds a monopoly position in Intel PC Operating Systems. Business users have long been aware of Microsoft's lock on office productivity applications that require them to use MS Office in order to remain compatible with their business partners and customers. And web-surfing users are now using Internet Explorer in a ratio of about 8:1 over alternative browsers.

    But one aspect of Microsoft's monopoly is more fundamental than any of those; the investment in skill, experience, training, and tools of Windows software developers themselves.

    Those programmers, who have logged many long sessions of coding for the Windows environments, and with their deep immersion in its assumptions, tools, and API's, represent millions of person-years of Microsoft assets.

    For years it has been a difficult decision for a professional developer to choose an environment other than Windows. The scale of that market dwarfs its competitors and opens to developers many more specialty markets than any alternative platform. Further, the sheer size of the Windows installed base is seen as a hedge against market change. Windows is perceived as a platform that will be with us for a long time to come.

    Because it can take years of effort to reach the highest levels of productivity in a complex development environment, Windows-specialized programmers have, through economic necessity, been unable to switch to a different platform. With a large majority of developers writing code for Windows, the continued dominance of Windows applications was also assured. The monopoly was elegantly self-perpetuating.

    Many companies, failing to appreciate the depth of Microsoft's monopoly and its determination to defend it, squandered valuable resources probing Microsoft's markets for an opportunity. After several spectacular failures, it seemed nearly impossible for such a locked market to break free of this cycle.

    It seemed impossible, that is, until recently. Windows is no longer leading the growth curve among operating systems. The near perfect seal at the margins of the monopoly, it turns out, is only effective against competitors with a requirement to make money.

    While Microsoft once made the fending off of mighty IBM look easy, the Linux phenomenon presents a very different kind of challenge. It needs no profits, corporate partnerships, or investors in order to succeed. Linux depends only on hobbyists' passion for programming and their self-imposed standards of quality in their own work. Further, the Linux community seems to draw motivation from its dissatisfaction with the computing landscape that Microsoft has created.

    This noncorporate juggernaut has grown so large that it is spilling into commercial markets on many fronts. Now, with the additional support of several large corporations, the expansion rate of Linux could actually accelerate.

    Much of the continued growth of Linux will come at the expense of Microsoft. Others will lose business along the way, of course, but the ubiquitous presense of Microsoft astride the market presents many targets that are simply too broad to miss.

    Unfortunately for Windows programmers, at some point the rapid growth of Linux will force the saturated Windows market to start shrinking. Soon thereafter, the seller's market for Windows programming services will become a buyer's market -- and pay scales will begin to drop. Although the computer industry has experienced many of these disruptions in the past as new competition entered the market, this will be the largest such contraction by far.

    Confidence in the impenetrable market lock of MS Windows is slowly fading. Some years from now when this trend reversal is complete and documented, we will look back to a single turning point to call the end of Windows' dominance. I'm making my pick a little prematurely. I think the critical point was IBM's decision to support and invest heavily in Linux.
    mail this link | permapage | score:9129 | -Ray, July 9, 2001 (Updated: April 18, 2007)

    Scripting: Put a clock in your bash terminal


    In the original version, the cursor positioning didn't work on my Mac OS X system. If that happens to you, try this simplified variant:
    while true
    tput sc
    tput cup 0 60
    echo -en `date +"%H:%M:%S %F"`
    tput rc
    sleep 1
    Also, note that you'll need to run either script in the background to use your terminal.
    The script saves the current cursor position with an ANSI escape sequence instruction. Then, using the tput command, the cursor is sent to row 0 (the top of the screen) and the last column minus 19 characters (19 is the length of HH:MM:SS YYYY-MM-DD). The formatted date command is displayed in green inverted color. The cursor is then sent back to its original position with another ANSI sequence that restores the original saved position.
    mail this link | permapage | score:9110 | -Ray, January 22, 2008
    More articles...
    Fine Art Online Gallery

    Recent headlines

    ROSA Desktop Fresh R1: For advanced users, but even better for new users

    Giada – Audio tool for DJs, live performers and electronic musicians

    Usability, user-friendliness and the Linux desktop

    Linux mail command examples: send mails from command line

    Plasma Media Center 1.1 and digiKam 3.3

    Tutorial: Replace Windows with Ubuntu 13.04

    Virtual Users/Domains with Postfix/Courier/MySQL/SquirrelMail (Debian 7)

    Sagemath in the Cloud and Sagemath 5.11

    Install Cinnamon on Fedora 19

    Tutorial: Running CS-Cart on Nginx on Debian 7/Ubuntu 13.04

    Dual-boot Ubuntu 12.04 and Windows 7 on a computer with 2 hard drives

    Unix: Shell Script Wrapper Examples

    How to install postgresql 9.2 on Ubuntu 13.04 Server

    ATA over Ethernet (AoE) (Ubuntu 12.04)

    4 third-party repositories for Fedora 19

    Pipelight – Using Silverlight in Linux browsers

    PC-BSD 8.2 review

    OpenShift Online: a non-developer guide

    OpenBSD Tutorial: Configure Ralink USB Wireless Adapter

    Install openQRM 5.1 on Debian 7

    Using Multiple PHP Versions (PHP-FPM FastCGI) With ISPConfig 3 (Ubuntu 12.04)

    Hand of Thief trojan and your favorite Linux distribution

    Currency Traders Telnet Game

    Linux Mint Debian 201204 MATE/Cinnamon review

    Tutorial: Debian 7 Samba Server with tdbsam

    Dual-boot Windows 7 and Ubuntu 12.04 on a PC with UEFI board, SSD and HDD

    Take Android Screenshots

    Perl One-Liners Explained: Handy Regular Expressions

    Using Git for Source Control

    FreeBSD 8.0: First Look

    Dual-boot PC-BSD 8.2 ZFS and Windows 7

    Linpus Lite 1.9 review

    e-book: Sed One-Liners Explained

    Tutorial: Automatically add a disclaimer to emails with alterMIME (Postfix on Debian 6)

    Fedora 19 review – Schrodingers Cat

    Installing NRPE on FreeBSD 9.0

    Detailed Error Handling In Bash

    Tutorial: Create an NFS-like Storage Server with GlusterFS on Ubuntu 12.10

    Python Client/Server Tutorial

    Apple DIY Repair


    Firefox sidebar

    Site map

    Site info

    News feed


    (to post)


    Articles are owned by their authors.   © 2000-2012 Ray Yeargin