diff --git a/Makefile b/Makefile
index a2d5da9f32eeab1eac6f4e40a4e88697814f70ab..fddb9c14e177b333b2e4ec07962f613d7d31fa30 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 CC=gcc -std=c99
 CFLAGS=-I./src -I./include
 LIB=
-OBJ=./src/utils.o
+OBJ=./src/utils.o ./src/commands.o
 
 %.o: %.c $(DEPS)
 	$(CC) -c -o $@ $< $(CFLAGS)
diff --git a/include/commands.h b/include/commands.h
new file mode 100644
index 0000000000000000000000000000000000000000..cef87396eaf3c171cd412fe4e527f7fb6d725e19
--- /dev/null
+++ b/include/commands.h
@@ -0,0 +1,10 @@
+#ifndef MYSH_COMMANDS_H_
+#define MYSH_COMMANDS_H_
+
+int do_cd(int argc, char** argv);
+int do_pwd(int argc, char** argv);
+
+int validate_cd_argv(int argc, char** argv);
+int validate_pwd_argv(int argc, char** argv);
+
+#endif // MYSH_COMMANDS_H_
diff --git a/src/commands.c b/src/commands.c
new file mode 100644
index 0000000000000000000000000000000000000000..2df0d4d8834de3f4990570f3f3fc22d63fb6cbe3
--- /dev/null
+++ b/src/commands.c
@@ -0,0 +1,28 @@
+#include <string.h>
+
+#include "commands.h"
+
+int do_cd(int argc, char** argv) {
+  if (!validate_cd_argv(argc, argv))
+    return -1;
+
+  // TODO: Fill it!
+  return 0;
+}
+
+int do_pwd(int argc, char** argv) {
+  if (!validate_pwd_argv(argc, argv))
+    return -1;
+
+  // TODO: Fill it!
+
+  return 0;
+}
+
+int validate_cd_argv(int argc, char** argv) {
+  // TODO: Fill it!
+}
+
+int validate_pwd_argv(int argc, char** argv) {
+  // TODO: Fill it!
+}
diff --git a/src/main.c b/src/main.c
index f8b643afbf2c84dc03b777743d3e53a22045cf49..27a83e097a188d4c905129df216b836de287f78e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "commands.h"
+#include "utils.h"
+
 int main()
 {
+  char buf[8096];
+  int argc;
+  char** argv;
+
+  // initialize command buffer
+  argv = (char**)malloc(32);
+  for (int i = 0; i < 32; ++i) {
+    argv[i] = (char*)malloc(8096);
+  }
+
+  while (1) {
+    fgets(buf, 8096, stdin);
+
+    mysh_parse_command(buf, &argc, argv);
+
+    if (strcmp(buf, "") == 0) {
+      continue;
+    } else if (strcmp(argv[0], "cd") == 0) {
+      do_cd(argc, argv);
+    } else if (strcmp(argv[0], "pwd") == 0) {
+      do_pwd(argc, argv);
+    } else if (strcmp(argv[0], "exit") == 0) {
+      break;
+    } else {
+      fprintf(stderr, "%s: command not found\n", argv[0]);
+    }
+  }
+
+  // destroy command buffer
+  for (int i = 0; i < 32; ++i) {
+    free(argv[i]);
+  }
+  free(argv);
+
   return 0;
 }
diff --git a/tests/src/command_parsing_test.cc b/tests/src/command_parsing_test.cc
index 65925de33b7287a07e51480d8ff3dd93660611fd..19165c13892f15d6870b7bfdc5fcfef82ed698d9 100644
--- a/tests/src/command_parsing_test.cc
+++ b/tests/src/command_parsing_test.cc
@@ -84,7 +84,7 @@ TEST(CommandParsingTest, EmptyCommand) {
   char** argv = alloc_string_array(1, 1024);
   int argc = -1;
 
-  mysh_parse_command("", &argc, argv);
+  mysh_parse_command("   \n \t    ", &argc, argv);
 
   EXPECT_EQ(argc, 1);
   EXPECT_STREQ(argv[0], "");