diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs
index 54b8eafc62c912d184fc096717092c347f60a480..4303bb34a4e4d82faeaf27224bf10e2ccd73cc57 100644
--- a/src/builtins/mod.rs
+++ b/src/builtins/mod.rs
@@ -21,7 +21,9 @@ use self::test::test;
 use self::variables::{alias, drop_alias, drop_array, drop_variable};
 
 use std::error::Error;
+use std::env;
 use std::io::{self, Write};
+use std::path::Path;
 
 use parser::QuoteTerminator;
 use shell::{self, FlowLogic, Shell, ShellHistory};
@@ -77,6 +79,7 @@ pub const BUILTINS: &'static BuiltinMap = &map!(
     "ends-with" => ends_with :"Evaluates if the supplied argument ends with a given string",
     "contains" => contains : "Evaluates if the supplied argument contains a given string",
     "exists" => builtin_exists : "Performs tests on files and text",
+    "which" => builtin_which : "Shows the full path of commands",
     "ion-docs" => ion_docs : "Opens the Ion manual"
 );
 
@@ -372,3 +375,38 @@ fn builtin_exists(args: &[&str], shell: &mut Shell) -> i32 {
         }
     }
 }
+
+fn builtin_which(args: &[&str], shell: &mut Shell) -> i32 {
+    if args[1..].len() != 1 {
+        let stderr = io::stderr();
+        let mut stderr = stderr.lock();
+        let _ = stderr.write_all(b"which takes one argument\n");
+        return BAD_ARG;
+    }
+
+    let command = args[1];
+
+    if let Some(alias) = shell.variables.aliases.get(command) {
+        println!("{}: alias to {}", command, alias);
+        SUCCESS
+    } else if shell.builtins.contains_key(command) {
+        println!("{}: built-in shell command", command);
+        SUCCESS
+    } else if shell.functions.contains_key(command) {
+        println!("{}: function", command);
+        SUCCESS
+    } else {
+        for path in env::var("PATH").unwrap_or("/bin".to_string())
+                                    .split(sys::PATH_SEPARATOR) {
+            let executable = Path::new(path).join(command);
+            if executable.is_file() {
+                println!("{}", executable.display());
+                return SUCCESS;
+            }
+
+        }
+
+        println!("{} not found", command);
+        FAILURE
+    }
+}