Posts tagged Linux

June 12, 2012 by Dave

Are you using Ubuntu and Sublime Text 2 and need a handy launcher icon? Here's a .desktop file That you can paste into ~/.local/share/applications/sublime_text.desktop or /usr/share/applications/sublime_text.desktop:

A couple things to note:

  • Remember to make this file executable.
  • This file runs the sublime_text binary. This assumes you already have the path to its parent directory in $PATH or symlinked to /usr/bin or something.
  • If you don't have the Sublime Text icon on your machine, grab it here and save it as ~/.local/share/icons/sublime_text.png.

    Once you've set this up, you can lock it to your launcher. Here's a screenshot:


February 09, 2012 by Dave

Ubuntu's Unity Interface has many handy features, one of which is a new launcher bar that supports Quicklists. Each launcher icon can have a customizable list of options that let you run the program however you want. Here's a quicklist for the popular webserver nginx.


  1. First, Install nginx-init-ubuntu.
  2. Add create a new file .local/share/applications/ named nginx.desktop and paste this inside:

    [Desktop Entry]
    Comment=Nginx Webserver
    Exec=sudo service nginx start
    [Start Shortcut Group]
    Name=Start Nginx
    Exec=sudo service nginx start
    [Stop Shortcut Group]
    Name=Stop Nginx
    Exec=sudo service nginx stop
    [Restart Shortcut Group]
    Name=Restart Nginx
    Exec=sudo service nginx restart
  3. Using your file manager (such as nautilus), drag .local/share/applications/nginx.desktop to the launcher.

January 26, 2012 by Dave

For those of you using nginx and debian-based distributions such as Ubuntu, Mepis, Mint, etc. you may have noticed that the init script on nginx's wiki doesn't work very well with newer distributions such as Ubuntu 10.04/11.10, etc. Instead, let's use upstart, which is much cleaner.

First, add this to /etc/init/nginx.conf:

description "Nginx HTTP Server"

start on filesystem
stop on runlevel [!2345]

exec /opt/nginx/sbin/nginx -g "daemon off;"

Note: By default, this script thinks nginx is in /opt/nginx. If your nginx configuration is different, change it to specify the correct location. start 'er up:

$ sudo start nginx
nginx start/running, process 11922

That's all there is to it. You can fork this script over at github if you want to make any changes or suggestions. This repo also includes an old System V style script if you need it.


This script is based off of Big Rock's upstart script from their RVM + Rails 3 + nginx + Phusion Passenger guide.

* Updated 2012-04-10: Added upstart instructions


January 23, 2012 by Dave

For those of you Linux users using Gnome, KDE, or Unity, here's a desktop entry file that you can use to create a shortcut/launcher icon to Aptana Studio 3. Just add this to /usr/share/applications or ~/.local/share/applications.

[Desktop Entry]
Name=Aptana Studio 3
Comment=The professional, open source development tool for the open web
GenericName=Aptana Studio

This assumes you've installed Aptana to /opt/aptana-studio-3, so if yours is in a different directory, be sure to change it.


Credit goes to Willington Vega for supplying the original desktop entry file. 


Shorewall is a great little firewall that's excellent for use in many linux distributions. It is highly configurable and a great alternative to working with iptables directly. It's especially easy to install on debian-based distros such as ubuntu, mint, mepis, etc. I'll be using ubuntu in this tutorial. Be sure to perform the steps of this guide on the physical machine as root. If you're doing this over ssh/terminal, you may get locked out during the configuration process. Let's get started!

Step 1 - Install Shorewall

Let's switch to root and install Shorewall using apt:

su -
apt-get install shorewall

Step 2 - Configure

Shorewall can be used in several different firewall configurations. If your linux machine is a dedicated server used for services like Apache or Samba, you'll be using a 1-interface configuration. If your linux machine is going to act as a router and firewall to an internal network, you'll be using a 2-interface configuration, and so on. Let's pretend our server is used for hosting websites, so we'll set up a 1-interface Shorewall configuration.

Shorewall's configuration files are stored in /etc/shorewall. Shorewall also comes with several example configurations you can use to get up and running quickly. Let's copy over the 1-interface example configuration files to get things going:

cp /usr/share/doc/shorewall/examples/one-interface/* /etc/shorewall

This will copy several files over to /etc/shorewall. Let's learn more about what these files do. Shorewall uses several configuration files. Here's a brief summary of each one:

  • zones - allows you to define specific zones that will used when defining policies and rules
  • interfaces - specifies which hardware devices and settings are assigned to each zone 
  • policy - contains general access rules and catchalls for traffic going to/from your zones
  • rules - defines allowed/restricted protocols, ports, etc. that are allowed to/from your zones

The two most important files here are policy and rules. Let's take a look at the policy file:

#SOURCE         DEST            POLICY          LOG LEVEL       LIMIT:BURST
$FW             net             ACCEPT
net             all             DROP            info
all             all             REJECT          info 

$FW is your firewalled network, in our case it's the server. net is the internet. The last line is important because it's the catchall. It tells Shorewall to reject all traffic that it doesn't know how to handle.

Next, let's look at the rules file. This defines which ports and protocols shorewall will handle.

#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE          
#                                                       PORT    PORT(S)         DEST            LIMIT         

# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
Ping(DROP)      net             $FW

# Allow the internet to connect to web server
ACCEPT net $FW tcp 80

# Allow telnet and ssh, port range 22-23
ACCEPT net $FW tcp 22:23

# Allow Outgoing SMTP Traffic on Multiple ports
ACCEPT $FW net tcp 25,26,465,587

These rules will allow several types of traffic. Shorewall also comes with many handy macros(as seen with the Ping macro above) that predefine several different protocols and services. They're located in /usr/share/shorewall. You can also create your own macros.

Step 3 - Start 'er up

Once you have your configuration all set up, start Shorewall.

shorewall start

That's it! You're now safe and sound behind a firewall. Don't you feel better?

Additional Resources

This is just a tiny showcase of Shorewall's features. You can do many other cool things with it as well. Be sure to check out the links below.


Gitolite is a git repository manager that lets users access git repositories on your server. The best part about gitolite is that you only need one linux user account, and you can change user access permissions to different repositories on the fly. You can also restrict access to a repository based on an individual commit, branch, tag, etc. This makes gitolite a great tool for corporate environments or if you want to allow a client to check out the latest source code you're developing for them.

Gitolite runs great on any linux server, such as Ubuntu, Mint, Mepis, Fedora, etc. This tutorial assumes you have git installed on your server and know how to use ssh and how SSH public key authentication works. In this tutorial, we'll be using two computers, the server(where all the repositories will be stored) and the workstation(where you will push/pull git repositories). I'm assuming that the workstation is also a unix/linux machine. Of course, you can use windows as well. Also, the workstation and server can be located on the same machine.

Step 1- Set up git user and create ssh public key

# On The Server
sudo useradd git # Create git user
sudo passwd git # Create git user's password. Remember This.
sudo su git # switch to git user 
echo "PATH=$HOME/bin:$PATH" > ~/.bashrc # Allows you to set up gitolite

# On Workstation as bob (This can also be a user on the same server as gitolite)
ssh-keygen # Generate follow steps, use NO password
scp ~/.ssh/ git@[host] # copy your pubkey to the git user's home directory, this will be used when 
installing gitolite. Substitute "localhost" for [host] if bob is a user on the same machine as git.

Step 2 - Install gitolite

Now we're going to install gitolite from Sitaram's official github repository. Start by logging in as the git user on your server.

# Install gitolite
git clone git://
gitolite/src/gl-system-install # install gitolite 
gl-setup ~/ # use bob's pubkey so he can administer gitolite

Step 3 - Configure gitolite-admin

Gitolite administration is done in a git repository called gitolite-admin, stored in the git user's default repo directory(~/repositories). In order to make changes to gitolite, the administrator (bob) needs to clone this repository to his account, make the changes, and push them back to the server. As bob, Let's go ahead and do this.

git clone git@[host]:gitolite-admin.git

Since gitolite-admin is a git repository itself, you can administer it from multiple machines, and you can also specify who has administrative access to gitolite, just like any other repo. Nice!

Step 4 - Adding Users

Let's add a user to gitolite. This user will be named alice, and we're going to give her read access to the myrepo repository. Since all gitolite authentication is done with ssh public keys, alice will need to give you her public key. Let's assume you have placed her public key in a file called, stored in your home directory.

cd ~/gitolite-admin # change to the gitolite admin repository
cp ~/ keydir # copy alice's public key to gitolite-admin

Next, let's specify alice's permissions in the gitolite configuration file, stored in conf/gitolite.conf:

repo myrepo
        RW+    =   bob # let bob read, write, and rewind
        R        =   alice

Save your changes to this file, make a commit, push your changes to gitolite, and you're done! Alice now has read access to the repository.

Cloning a repository for the first time

Since alice now has read access to myrepo, she needs to clone it to her workstation. Here's what alice will type in:

git clone [user]@[host]:[repo].git # ie: git clone

Limiting access to a specific branch, tag, etc.

You can also limit access to a repository based on a particular branch, tag, commit, etc.

repo @myrepo
    RW  alice$               = alice # let alice read/write to the 'alice' branch
    RW  ali-                = alice # let alice read/write to any branch that starts with 'ali' 
    RW  refs/tags/v[0-9]   = alice # let alice read/write to any tag v0-v9

This is just the tip of the iceberg! Gitolite allows you to use macros for user/repository groups, and much more. Be sure to check out the official documentation below.

Additional Resources


November 20, 2010 by Dave

A Little History of Linux Device Management

In linux, normally your hardware devices are stored as files(though they're actually called nodes) in the /dev directory. So if I want to access my USB serial adapter I just plugged in, I would work with something like /dev/ttyUSB1. Pretty simple, eh?

Well, a process called udev takes all of your hardware and creates these nodes based on rules. Therefore, we can tell linux to create a device called /dev/usbserial1 instead of /dev/ttyUSB1. The best part about this is that linux will remember the rules you make so your devices will always be created with the same name. Normally linux just assigns the name based on whatever is available(ttyUSB1, ttyUSB2, and so on), which can get frustrating. I'll show you how to do this!

Step 1 - The Rules of the Rules

To create a udev rule, create a file in /etc/udev/rules.d. Rules are set up similar to runlevel scripts, so name it something like:

Rules get executed based on number(lowest to highest).

The contents of your rule file should look something like this:

ATTR{serial}=="xxxx", NAME="usbserial1", SYMLINK+="anothernamefor_usbserial1"

The first attribute, ATTR{serial}, is a attribute of the device, and the second, NAME, is what you want the name of the device to be in /dev. SYMLINK is a symbolic link(or alias) that will point the device. This is optional.

Let's find out how to get the attributes for your device.

Step 2 - Learn about your device

To see all the attributes and information about a device, run this command:

udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB1)

You'll get a whole bunch of data information for your device, followed by the parent device's information(ie: a usb host controller).

You can use any of the attributes you see in the rules file, but try picking something unique to the device. ATTR{serial} works great.

Step 3 - Test it Out!

Once your rule is written, run:

udevadm control --reload-rules

This will reload udev's rules, so the next time you plug in your device, your device will get its new name. If you don't feel like unplugging  your device, just run this instead:

udevadm test -a -p $(udevadm info -q path -n /dev/ttyUSB1)

If your linux kernel does not support inotify, you may also need to run this:


That's all there is to it!

This is just the tip of the iceberg when it comes to writing udev rules. You can also create symlinks, use filters and interpolation, and more!


In this example, I am using a debian-based linux distribution: Linux Mint.

The command: udevadm info is a replacement for the deprecated udevinfo.

There's also an excellent tutorial on writing udev rules here.


Here's another approach to replacing text strings in files recursively(in all subdirectories). This approach uses linux's replace command instead of sed, and Ruby's Find module to get a list of all files in the current directory(including all subdirectories). This script will handle any special regexp characters as well.

#!/usr/bin/env ruby

# Recursive String Replacement - Approach 2, starting in current dir.
# Author: Dave Hulihan

require 'find'

def get_dirs # get all directories(recursive), starting in current 
 dir_array = 
 Find.find('./') do |f| 
 	dir_array << f if ! # add only non-directories
 return dir_array

if ARGV.length < 2
        puts "Usage: recursive_replace \"[string1]\" \"[string2]\""
        exit 0

@string1 = ARGV[0]
@string2 = ARGV[1]

puts "Replacing #{@string1} with #{@string2}..."
directories = get_dirs
for directory in directories
  if directory && directory != "." && directory != ".." 
	  exec_string = "replace \"#{@string1}\" \"#{@string2}\" -- #{directory}"
	  #puts "In #{directory}"
	  # puts exec_string 

puts "Done!"


Have you ever been working in linux, and you wanted to replace a certain string of text with another string of text, from several files, in several directories? Well, now you can!  Normally you can do this using linux's sed or replace command, but they don't work well when you want to recursively descend into subdirectories. Here's a quick ruby script I wrote that will take two arguments, the old string(you want replaced) and the new string(that will do the replacin'):

#!/usr/bin/env ruby

require "eregex"

# Recursive String Replacement, starting in current dir.
# Author: Dave Hulihan

if ARGV.length < 2
        puts "Usage: recursive_replace [string1] [string2]"
        exit 0

@string1 = ARGV[0]
@string2 = ARGV[1]

puts "Replacing #{@string1} with #{@string2}..."

@string1 = Regexp.escape(@string1) # escape any special characters
@string2 = Regexp.escape(@string2)

exec("find ./ -type f | xargs sed -i 's/#{@string1}/#{@string2}/g'")

puts "Done!"

This script uses linux's find and sed commands together to perform a recursive file search with string replacement.