Vim gems

Wow! Looong time no see! If you’re wondering where I’ve been, about three months ago, I got a job as a web-developer, which ironically, leaves me less time to maintain my techblog. :)

Anyway, I’m currently working on a post about learning Ruby and I’ve got a few other ideas up my sleeve (youtube api, maybe something on node.js, and perhaps that long-neglected wordpress post). But today, I’m just going to drop a few vim gems in your lap: Recently, I found a seven part series of posts from Peteris Krumins of CatOnMat about the best vim plugins. I consider myself pretty expert in basic vim — keyboard shortcuts, that kind of thing — but I’ve yet to dive into extending it. So this is the next frontier!

Unfortunately, I haven’t gotten around to reading all of them, but who knows when that will be? :) It’s Peteris Krumins, I’m sure they’ll all be good. So here you go, links to all seven parts:

Part I: surround.vim
Part II: repeat.vim
Part III: matchit.vim
Part IV: snipmate.vim
Part V: a.vim
Part VI: nerd_tree.vim
Part VII: ragtag.vim

Also, did you know bash has a vi mode? I sure didn’t before this article.

Cheers!

Introduction to MySQL on Ubuntu

For ages, I avoided — was even a little scared — of databases. I had heard all kinds of horror stories about databases being overused in commercial applications, and I got the impression that I should stay away from them if I didn’t absolutely need one. That wasn’t too hard: if you’re a hobbyist programmer with a decent knowledge of Bash, it’s a long time before you need a database.

But when it came to learning WordPress development, it wasn’t my choice; that was just the way it was. So I grumbled a little, dragged my feet for a few days, and buckled down and learned some MySQL. In the end, as with most things, it turned out to be not nearly as difficult as I had imagined and sometimes even fun. :)

Introduction

Before we dive into working with MySQL, I want to explain a few things about MySQL and databases in general. If this is old news for you, feel free to skip on over.

First, you might be wondering what the difference is between SQL and MySQL. SQL (which stands for Structured Query Language) is a programming language designed specifically for working with databases. Database servers that want to use SQL will implement the language specification. MySQL is one such database server; others include SQLite, PostgreSQL, Oracle, and SQL Server.

It’s helpful to know how a database is structured. (It’s very simple, but it was by no means obvious to me when I first started out.) You can think of the MySQL server as a big container where everything is stored. Within it, we have a bunch of databases, and each database keeps its data in a collection of tables. Each database usually belongs to a different application, and each can organize their data into tables however is best for them.

The way MySQL is set up, there is a MySQL server and a MySQL client. What’s the difference? The server is where all of your data is stored. The client on the other hand is a program that allows you to access and manipulate that data. This separation of actual data from its representation buys you a lot of freedom. You can choose between several MySQL client applications for working with your data, and you can even do it from someone else’s computer.

This might seem confusing but actually, it’s a very familiar concept. Think of the the internet. You can view a webpage using whichever browser you please. You can also see the webpage from a different computer than the one where the actual files are stored (obviously, this site isn’t on your machine; it’s on Bluehost’s server somewhere far away). The file system also works this way. You can browse the same data using Nautilus or the terminal, and you can ssh into other computers to view their data.

(Hopefully, that makes sense. If not, try the explanation here.)

As I mentioned, there are a variety of MySQL client applications available. I’m not very familiar with the options — being a terminal junkie, I just use the command-line interface (and that’s what I’ll be going over in this tutorial). However, if that’s not your cup of tea, there are a variety of graphical applications available, the most notable of which is phpMyAdmin, which runs in the browser and is written in PHP.

Anyway, let’s go ahead and get started.

Installation

To install MySQL, run

$ sudo aptitude install mysql-server

This will get us a MySQL server and a command-line client for working with it. If you’d like a different client, such as phpMyAdmin, you’ll have to install it separately.

During the installation, MySQL will prompt you to enter a password. Remember it well: That’ll be the password for your MySQL root account.

Note that MySQL users and passwords have nothing whatsoever to do with your ubuntu users and passwords, despite being named similar things like root@localhost. I’ll touch on MySQL users and permissions later on.

MySQL Basics

Most of the time, you won’t be manipulating your databases by hand — in fact, it’s strongly discouraged. Usually, you’ll be working through PHP or Perl or some other API. However, I find going in and plugging commands by hand to be the most effective way to figure out how everything works. Here’s a whirlwind tour of the most common operations. Let’s get started!

Setup

The first thing you’ll need to do is to log in:

$ mysql -u root -p

It’ll prompt you for your password (the one you entered during installation), greet you with a standard message, and then you should see a prompt that looks like this:

mysql> 

At this point, you can issue SQL commands to the database. A quick note: SQL keywords are case insensitive, but traditionally they’re written in all caps. A lot of programmers (myself included) find this really annoying and do everything in lowercase. It’s ultimately a matter of preference. In this tutorial, I went ahead and stuck to the uppercase convention because it distinguishes the keywords from the non-keywords. But if it annoys you, by all means switch.

By the way, it’s worth noting that you’re on the root account, which (similar to being root on your linux machine) means you could do quite a lot of damage. For now, just be careful about entering commands, and in a little bit, I’ll show you how to create a new user with limited privileges.

The first thing we’ll do is take a look at what databases are available.

mysql> SHOW DATABASES;
+-----------------------+
| Database              |
+-----------------------+
| information_schema    |
| mysql                 |
| phpmyadmin            |
| wordpress             |
+-----------------------+

If you’re on a fresh install, you’ll see information_schema and mysql. If your server is being used by other applications, like WordPress, you’ll probably see a few more.

Obviously, we don’t want to mess up any existing databases, so let’s create our own to play with, named test:

mysql> CREATE DATABASE test;

If you do another SHOW DATABASES; you should see your new database on the list. Now we can create a new user with access to only our test database. I’ll call mine “test_user” and make the password simply “password”. You can, of course, use whatever values you like.

mysql> CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON test.* TO 'test_user'@'localhost';
mysql> FLUSH PRIVILEGES;

The first two statements creates the user and grants it all privileges on our test database; the FLUSH PRIVILEGES; simply tells MySQL to update the database permissions.

You now have a user with all privileges on our dummy database test, but none on any of the others. Go ahead and Ctrl-D your MySQL session and log in as your new user:

mysql> mysql -u test_user -p

Now, if you do a SHOW DATABASES;, the only databases you can see are test and information_schema.

To do anything with our new database, we need to tell MySQL to “enter” it:

mysql> USE test;

Now we’re ready to create some tables and enter some data.

Table Operations

To see a list of the tables in a database, you can say:

mysql> SHOW TABLES;

Obviously, we don’t have any yet. So let’s make one.

mysql> CREATE TABLE useful_info (
    -> first varchar(30),
    -> last varchar(30),
    -> age int,
    -> gender char(1),
    -> PRIMARY KEY (first, last)
    -> );

This creates a table called useful_info with four columns named first, last, age, and gender. Next to each is the datatype of the column. Finally, we use the columns first and last as the primary key. A primary key ensures that your rows are unique; when you specify more than one column as the primary key, the combination has to be unique. Let’s see it in action:

mysql> INSERT INTO useful_info (first, last, age, gender) VALUES ('John', 'Doe', 32, 'm');

This should produce a response like Query OK, 1 row affected (0.15 sec) . Now, if I try to insert someone else named John Doe into the table, I’ll get an error:

mysql> INSERT INTO useful_info (first, last, age, gender) VALUES ('John', 'Doe', 21, 'm');
ERROR 1062 (23000): Duplicate entry 'John-Doe' for key 'PRIMARY'

As you can see, you have to know a lot about your table before you can do anything with it. If you need a quick refresher, you can get a summary of your columns by saying:

mysql> DESCRIBE useful_info;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| first  | varchar(30) | NO   | PRI |         |       |
| last   | varchar(30) | NO   | PRI |         |       |
| age    | int(11)     | YES  |     | NULL    |       |
| gender | char(1)     | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+

Go ahead and populate your table. Play with it a little. :)

Once you have a decent roundup of people, you’ll eventually want to see your data. To get data from a table, we use the SELECT command. This will fetch the entire table:

mysql> SELECT * FROM useful_info;
+-------+-------+------+--------+
| first | last  | age  | gender |
+-------+-------+------+--------+
| John  | Doe   |   32 | m      |
| Jane  | Doe   |   28 | f      |
| Jenny | Lane  |   21 | f      |
| Aaron | Adams |   25 | m      |
+-------+-------+------+--------+

If you’d like to be more selective, you can restrict your search to certain columns …

mysql> SELECT first, last FROM useful_info;
+-------+-------+
| first | last  |
+-------+-------+
| Aaron | Adams |
| Jane  | Doe   |
| Jenny | Lane  |
| John  | Doe   |
+-------+-------+

… or certain rows …

mysql> SELECT * FROM useful_info WHERE first = 'John' AND last = 'Doe';
+-------+------+------+--------+
| first | last | age  | gender |
+-------+------+------+--------+
| John  | Doe  |   32 | m      |
+-------+------+------+--------+

… or both.

mysql> SELECT first, last FROM useful_info WHERE first = 'John' AND last = 'Doe';
+-------+------+
| first | last |
+-------+------+
| John  | Doe  |
+-------+------+

Lovely!

What if you want to change your table in any way? You could delete the whole table and recreate it, but that’s a bit of a hassle, seeing as you’d lose all of your data. Fortunately, there’s a command to alter the table. There’s a lot of things you can do with the alter keyword, but for simplicity, let’s just change the name of a column. Maybe you keep getting confused what first means and would like to make it clearer:

mysql> ALTER TABLE useful_info
    -> CHANGE COLUMN first first_name varchar(30);

Now if we describe our table, you’ll see that first has been changed to first_name:

mysql> DESCRIBE useful_info;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| first_name | varchar(30) | NO   | PRI |         |       |
| last       | varchar(30) | NO   | PRI |         |       |
| age        | int(11)     | YES  |     | NULL    |       |
| gender     | char(1)     | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
Deletion

Sometimes, you just need to get rid of something. Before you do though, realize that all of your data will be erased. Use these commands with caution: There is no going back!

To delete our table useful_info:

mysql> DROP TABLE useful_info;

To remove the whole test database:

mysql> DROP DATABASE test;

And to remove the user we created for our database (I had to be logged in as root to do this):

mysql> DROP USER 'test_user'@'localhost';

And you should be back to where you started.

MySQL Permissions

MySQL has a flexible and extensive users and permissions system. I’ll just touch on the basics here.

All the information for users and their permissions is kept in the mysql database. You’ll need to be root to access it. So after you’ve logged in, type

mysql> USE mysql;

Go ahead and check out what tables mysql keeps around:

mysql> SHOW TABLES;
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| ndb_binlog_index          |
| plugin                    |
| proc                      |
| procs_priv                |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+

The table we’re interested in is the user table, where (surprise!) the users are kept. Let’s take a look at what columns it has.

mysql> DESCRIBE user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Event_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Trigger_priv          | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     | NULL    |       |
| x509_issuer           | blob                              | NO   |     | NULL    |       |
| x509_subject          | blob                              | NO   |     | NULL    |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+

The first thing of interest is the columns Host and User. Together, they specify an individual user (you’ll notice that they’re the primary key). Notice I emphasize the “together.” This is similar to users on different linux machines: darth@deathstar isn’t necessary the same guy as darth@thedarkside. If that fails to make sense, just think of them as first and last names: George Bush is a very different person than George Washington.

The other columns specify the different privileges that the user can have. Let’s use the select privilege as an example (the Select_priv column). The user table is the master table. Suppose you receive a Y for the select privilege. That means you can perform SELECT queries on every database on the server. However, suppose you get a N. That doesn’t mean you have no select privileges, just that you can’t do it anywhere you want. At that point, MySQL will inspect a succession of other tables to figure out where you have permission to do selects.

As an illustration, let’s take a look at the list of users and their select and insert privileges.

mysql> SELECT Host, User, Select_priv, Insert_priv FROM user;
+-----------+------------------+-------------+-------------+
| Host      | User             | Select_priv | Insert_priv |
+-----------+------------------+-------------+-------------+
| localhost | root             | Y           | Y           |
| rose      | root             | Y           | Y           |
| 127.0.0.1 | root             | Y           | Y           |
| localhost | debian-sys-maint | Y           | Y           |
| localhost | wordpress        | N           | N           |
| localhost | phpmyadmin       | N           | N           |
+-----------+------------------+-------------+-------------+

You should see several root users at hostnames that represent your computer (localhost, your machine name, your IP address). They should have Y under both Select_priv and Insert_priv. If you created a user for your test database above and you haven’t deleted it, you should also see it on the list. It should have an N in both privilege columns — that makes sense because it only has access to your test database.

Okay, that’s all I’m going to say about users and permissions. For more details, take a look at this article (where I learned all this to begin with).

Resources

Now that you’ve got a taste of MySQL, you’re probably itching to learn more. I’ve sprinkled links to helpful resources throughout the post, but for convenience, I’ll present them again here, along with some others.

First, learning the SQL language is undoubtedly helpful. Even though every implementation of SQL is slightly different, the majority of it will be the same. I went through the w3schools tutorial, but there are plenty of others as well.

There are also many tutorials on MySQL in particular. I’ve not really used any — most of what I know, I’ve learned by searching for specific tasks — but sometimes, it’s nice to sit down and fill in all the gaps.

Last but certainly not least, there’s the MySQL documentation. It’s definitely not for the faint of heart! But it’s also the most thorough and definitive source of information you’ll get.

Finally, here are articles on specific topics that I found to be very helpful. I highly recommend starting with this list of common commands; it’s a great place to get an overview before researching specific syntaxes.

The CREATE TABLE and ALTER TABLE syntaxes
MySQL datatypes: An overview, and the comprehensive reference
The SELECT command, string comparisons, and regular expressions
The CREATE USER and GRANT syntaxes
An explanation of MySQL Permissions

Cheers! I hope this has been helpful!

Enable PHP in Userdirs

In my Apache post, I mentioned that it was a nasty process enabling php in per-user directories. Well, I did another google search today, and it turns out I was wrong — it’s actually very easy!

All you have to do is open the /etc/apache2/mods-enabled/php5.conf file and comment out this bit of code:

<IfModule mod_userdir.c>
    <Directory /home/*/public_html>
        php_admin_value engine Off
    </Directory>
</IfModule>

Remember, comments in Apache begin with #. Also, just in case you were tempted, the file warns against changing the Off to On, as that would prevent any .htaccess files from disabling the engine.

Now, restart Apache and you should be good to go:

$ sudo /etc/init.d/apache2 restart

Many thanks to this article, where I found this information!

How to Install Apache on Ubuntu

When learning web development, it isn’t long before you need something more than pointing your browser at a local file. You want to learn PHP, AJAX, or WordPress … and that means a web server. Fortunately, it’s not too hard to get one installed on your local machine.

In this post, I’m going to show you the simplest way to get an Apache server up and running on Ubuntu, plus some helpful notes that you can either read now or come back to later.

I’m by no means an Apache expert … but then again, that’s why I’m writing this. Most of what I know was learned by prowing forums, digging through obscure documentation, and banging my head against a brick wall over and over again (as well as purging Apache several times). My hope is that these notes will be helpful to some other beginner and perhaps prevent a concussion or two. :)

Installation

To install Apache, open a terminal and run

$ sudo aptitude install apache2

Yep, that’s it! Now, point your browser at http://localhost/. You should see the default index.html page.

Where is everything?

Now that you’ve got Apache, you’re no doubt wondering how to do anything with it. Where is everything and how can you add content?

Browser address and content

First things first. In the browser, your apache server address is http://localhost/. You should also be able to use the name of your machine: http://myubuntubox/.

The content you’re seeing is in /var/www/. You could work directly in there, but you’d have to sudo everything, which is cumbersome and not very safe. My advice is to set up a folder in your home directory where you put all of your content. Then symlink it into /var/www/.

For example:

$ cd
$ mkdir my-web-content
$ cd /var/www/
$ ln -s ~/my-web-content ./

FYI, the way I do it is I keep a folder in my home directory called public_html that is symlinked into /var/www/. I leave it empty by default and create symlinks to any projects I’m working on; when I’m done, I remove them.

If you’re wondering, Apache is by default configured to follow symlinks, so that’s not a problem.

Configuration files

Now for the less-visible but all-important back end. All of your Apache configuration files are located in /etc/apache2/. Try to leave them alone if you don’t need to touch them. If you’re going to change anything, make copies of the originals before doing so. Why all the paranoia? If you mess up Apache, purging and reinstalling is not always a cakewalk.

Now, I’m about to say something very important: httpd.conf is now deprecated!. If you go to /etc/apache2/ and open httpd.conf, it will be empty!!!.

Okay, let me back up and explain myself here, lest you think me crazy. In older versions of Apache, httpd.conf was the master configuration file with all the important settings. If you needed to change anything, chances were that it was in httpd.conf. In recent versions, they’ve decentralized all these settings. Anyway, the reason I say this with such urgency is that in just about any Apache forum, the first thing that the well-meaning respondents will tell you to do is to go into httpd.conf and change something. You will follow their instructions … only to be faced with a blank file. You will then think that (1) something is wrong with your installation, or (2) you are insane. Neither is in fact the case.

Unfortunately, up-to-date advice on Apache configuration is scarce and far between. I’ve found only a handful of websites that actually acknowledge the emptiness of httpd.conf (which has become a bit of a litmus test in my book).

Okay, moving on …

Restart Apache

You’ll periodically need to restart your Apache server after you make some configuration change. To do that, run

$ sudo /etc/init.d/apache2 restart

Usually, Apache will tell you when you need to restart: Run '/etc/init.d/apache2 restart' to activate new configuration!

Note: There are several different commands you can use to “restart” Apache (reload is another one). Honestly, I never entirely figured out the difference between them; I’ve always just used restart. It’s the sledgehammer of the bunch, kind of like rebooting your machine as opposed to logging out and back in. I’m sure it’s not a good idea for big commerical setups, but for a small local server on which nothing critical depends, I don’t know that there’s any harm. It’s fast and most importantly, it always works; whereas in some situations the other commands aren’t enough.

Permissions

Apache runs as a user called www-data. To load your files, Apache needs read acccess. This can be tricky if you’re keeping the files in your home directory and symlinking into /var/www/.

My way of simplifying this is to add www-data to my user group, and me to www-data‘s usergroup:

$ sudo adduser username www-data
$ sudo adduser www-data username

You will need to restart Apache at this point. You may also need to log out and back in.

Now, you can own all of your web content. Just make sure your group has read access. (However avoid the executable bit on files: According to the hubby, it can cause problems, besides being a general safety risk.)

$ chown -R username:username public_html
$ chmod -R a+r public_html

If Apache is having trouble accessing your files, check that it has read access to your files and all folders in their path.

Modules

Apache modules are like plugins that you can turn on and off. They can be very helpful and some, like mod_rewrite, are required by a lot of software to achieve full functionality (e.g. WordPress pretty permalinks).

Find Modules

Apache comes with a bunch of modules. You can find the list of available modules in /etc/apache2/mods-available/. If it’s in there, you already have that module; however, it may not be enabled. The list of enabled modules is in /etc/apache2/mods-enabled/.

Enable a module

To enable a module, first find its name — that’s the part before the .conf or .load in the file name. For example, if you see the files userdir.conf and userdir.load in your mods-available folder, the module’s name is userdir. (See example below.)

Once you know what it’s called, you simply run:

$ sudo a2enmod <module-name>

You’ll need to restart Apache for it to take effect.

Disable a module

To disable a module, you use the companion command

$ sudo a2dismod <module-name>
Check that a module is running

To get a list of modules that are running, use this command:

$ sudo apache2ctl -M
Per-User Directories

The module userdir lets you have per-user directories, which be nice if if you have more than one user that wants to work with the webserver. Since this will also double as a good example for the above commands, I’ll go ahead and walk you through it.

First, enable the userdir module and restart apache.

$ sudo a2enmod userdir
$ sudo /etc/init.d/apache2 restart

Then go to your home directory and create a folder called public_html (it can be a symlink). This folder houses the contents of your per-user directory.

The browser address of your per-user directory is http://localhost/~username/. For example, if your username were janesmith, your per-user directory would be in http://localhost/~janesmith/. Once there, you should see the contents of your public_html folder.

One major drawback of using a per-user directory is that by default, PHP is not enabled. That means that if you point your browser at a PHP file, you’ll end up downloading it instead of executing the code. You can of course configure Apache to enable PHP, but my brief investigation into the subject showed that it was by no means straightforward. If you want PHP support, my advice is to symlink into /var/www/.

[Update: I did another search and it turns out that it’s not hard at all to enable PHP in userdirs. Check out this post for details.]

Purge Apache

Hopefully, you’ll be careful with your installation and you’ll never need this section. But if you do, well, I feel your pain. It happens. :)

Purging Apache can be a pill. The first time I tried it, I spent hours hunting down all of its tentacles, ended up with a bunch of broken packages, and finally came out with a fresh copy. I’ve been more careful ever since.

If you have to purge, the best list I’ve ever found is the one on the Ubuntu ApacheMySQLPHP page:


apache2 apache2-mpm-prefork apache2-utils apache2.2-common libapache2-mod-php5 libapr1 libaprutil1 libdbd-mysql-perl libdbi-perl libmysqlclient15off libnet-daemon-perl libplrpc-perl libpq5 mysql-client-5.0 mysql-common mysql-server mysql-server-5.0 php5-common php5-mysql

Notice that this purges the entire LAMP stack, including MySQL and PHP. If you don’t have those installed, then it’s not a problem; aptitude is pretty smart about figuring that out. However, if you do have them installed and would like to keep them, you’ll have to try singling out only the packages that are related to Apache. The following list worked for me:


apache2 apache2-mpm-prefork apache2-utils apache2.2-common libapache2-mod-php5 libapr1 libaprutil1

If neither works very well for you, you could try “reversing” the install. This is the list of packages that aptitude installed when I installed Apache:


apache2 apache2-mpm-worker{a} apache2-utils{a} apache2.2-bin{a} apache2.2-common{a} libapr1{a} libaprutil1{a} libaprutil1-dbd-sqlite3{a} libaprutil1-ldap{a}

Whichever list you choose, the syntax you want is

$ sudo aptitude purge <list of packages>

Then remove its etc folder if it’s still there:

$ sudo rm -rf /etc/apache2/

Now, try to reinstall. Hopefully, you won’t have broken packages. If you do, follow the package manager’s instructions for fixing them.

Well that’s all! I hope that was helpful. Stay tuned for posts on MySQL and WordPress.

Vim: Show Line Count in Visual Mode

Last year, I worked a great job writing little scripts. My office machine (an ancient thing running Windows 2000) had a gvim installation with an incredibly cool feature I had never seen anywhere else: it showed you how many lines you had highlighted in visual mode.

At the time, I, alas, completely took it for granted. Only several months after I left did I start wondering how I could get that feature back. Many hours of googling yielded nothing, so I fell back to my last line of defense: the Nabble vim forum.

Now, let me pause to say that this vim forum has been one of the best things I’ve ever used. I’ve posted two or three questions so far and gotten a helpful response within 24 hours of each. To the people who hang around places like that and answer my questions, my personal thanks and a big fat hug!

Anyway, I posted my question on the forum and like clockwork, I got a response: set showcmd. I slapped that in my vimrc and I’ve been enjoying my lovely line counts since. For those of you interested in what exactly showcmd is supposed to do, I copied this out of vim help:

Show (partial) command in the last line of the screen. Set this option off if your terminal is slow.

In Visual mode the size of the selected area is shown:
– When selecting characters within a line, the number of characters.
– When selecting more than one line, the number of lines.
– When selecting a block, the size in screen characters: {lines}x{columns}.

Hello world!

Hi, I’m Joyce. Welcome to my techblog, where I’ll be sharing my adventures as a young programmer, web-designer, and linux sys-admin (among other things).

A little bit about me: I’m 22 years old, and I started out as a completely normal person: a point-and-click Windows user. Then I met my now-husband, a crazy functional-language-enthusiast hacker guy who lured me into linux territory with promises of hassle-free web browsing (no more Clean Access, our campus’s notoriously annoying virus protection software). Five years later, I use the command line for everything, I have a dozen programming languages installed (including at least two versions of lisp), and I often catch myself typing vim key bindings inside my browser. I guess I have to admit that I’m a hacker too. :)

But I’m far from experienced. Every day, I run into new challenges. My things-to-learn list includes everything from Apache to bash to Ruby on Rails (and would probably take a few hundred lifetimes to get through). And I think I might actually faint dead away if our internet connection ever went out, severing me from the support forums that I rely on to get through my projects every day.

I’ve grown to really appreciate that community support, and here on this blog, I want to give a little bit back. I’ve actually wanted to for a long time, but I’ve always felt unqualified. I’m no expert. Who am I to be putting out how-tos? But my guilt eventually overcame my fear; my guilt and my gratitude. After all, where would I be without the little tutorials and tips that people write up that just happen to solve my problem? What if those people had decided not to write? By now, I’ve led enough frustrating searches for nonexistent documentation that this prospect strikes very real fear into my heart. And so I’ve decided to add what little I know into the pool.

So here I am! I hope you’ll join me on my crazy technological adventures, and I hope that what I write will be helpful … or at least entertaining. :D I’m looking forward to it!