diff --git a/blash.js b/blash.js
index 31bfa9a..9f54b7e 100644
--- a/blash.js
+++ b/blash.js
@@ -206,10 +206,7 @@ function blash ()
 					}
 				}
 
-				if ( dirs.length == 0 )
-				{
-					this.cmdOut.innerHTML = '<br/>Sorry, no matches for `' + this.prompt.value + "'";
-				} else if ( dirs.length == 1 ) {
+				if ( dirs.length == 1 ) {
 					this.prompt.value = this.prompt.value.replace ( arg, dirs[0].name + (( dirs[0].type == 'directory' ) ? '/' : '' ));
 				} else {
 					this.cmdOut.innerHTML = '';
@@ -301,8 +298,35 @@ function blash ()
 			arg = this.path + '/' + arg;
 		}
 
-		arg = arg.replace ( /\/*$/, '' );
 		arg = arg.replace ( /\/+/, '/' );
+
+		if ( arg != '/' )
+		{
+			arg = arg.replace ( /\/*$/, '' );
+		}
+
+		while ( arg.match ( /^(.+?\/?\.\.)/ ))
+		{
+			var part = RegExp.$1;
+
+			if ( arg.match ( /^(.+?)\/?\.\./ ))
+			{
+				if ( RegExp.$1 == '/' )
+				{
+					arg = arg.replace ( part, '/' );
+				} else {
+					part.match ( /^(.*)\/[^\/]*\/\.\..*$/ );
+					var sup = RegExp.$1;
+					arg = arg.replace ( part, sup );
+
+					if ( arg.length == 0 )
+					{
+						arg = '/';
+					}
+				}
+			}
+		}
+
 		return arg;
 	}
 }
diff --git a/blash.json b/blash.json
index 48c1e97..d5abcc2 100644
--- a/blash.json
+++ b/blash.json
@@ -67,6 +67,7 @@
 	],
 
 	"commands" : [
+		"cat",
 		"cd",
 		"ls",
 		"man",
diff --git a/commands/cat.json b/commands/cat.json
new file mode 100644
index 0000000..753ca61
--- /dev/null
+++ b/commands/cat.json
@@ -0,0 +1,45 @@
+{
+	"name" : "cat",
+
+	"info" : {
+		"syntax" : "cat &lt;file&gt;",
+		"brief" : "Show the content of a page",
+	},
+
+	"action" : function ( arg )
+	{
+		var out = '';
+
+		if ( !arg || arg.length == 0 )
+		{
+			return "Argument required<br/>\n";
+		}
+
+		var found = false;
+		var dir = shell.json.directories;
+		arg = shell.expandPath ( arg );
+
+		for ( var i=0; i < dir.length && !found; i++ )
+		{
+			if ( dir[i].path == arg )
+			{
+				found = true;
+
+				if ( dir[i].type == 'directory' )
+				{
+					return "cat: " + dir[i].path + ": Is a directory<br/>\n";
+				} else {
+					if ( dir[i].href )
+					{
+						window.open ( dir[i].href );
+					} else if ( dir[i].content ) {
+						return dir[i].content + "<br/>\n";
+					}
+				}
+			}
+		}
+
+		return out;
+	},
+}
+
diff --git a/commands/cd.json b/commands/cd.json
index 881bf44..e1665fb 100644
--- a/commands/cd.json
+++ b/commands/cd.json
@@ -15,15 +15,8 @@
 			return "Parameter expected<br/>\n";
 		}
 
-		arg = arg.replace ( /\/$/, '' );
-
-		if ( arg.match ( /^[^\/]/ ))
-		{
-			arg = this.path + '/' + arg;
-			arg = arg.replace ( /\/+/, '/' );
-		}
-
 		var found = false;
+		arg = shell.expandPath ( arg );
 
 		for ( var i=0; i < shell.json.directories.length && !found; i++ )
 		{