Click here to Skip to main content
Click here to Skip to main content

Simple Unix Like commands using C#

By , 8 Feb 2012
 

Introduction

This article presents some small toy console applications that emulate the Unix command like behavior on Windows.

Background

A while ago, my cousin (age: 10 years approx) came to me and asked me to install Unix on his computer. I asked him why he needed that, as a 10 year boy has little to do with Unix. He then told me that he needed to practice an assignment that involves running some Unix commands. He showed me a list of commands that he needed to run.

  • ls
  • cd
  • pwd
  • mkdir
  • rmdir
  • cp
  • mv
  • rm
  • cat
  • more
  • grep
  • whoami
  • ps

I was not ready to put Linux on his machine just to run these basic commands. I could give him something like "cygwin" or "coreutils" and he would be fine. Then I thought, Windows already has these commands but with some other names so why not just create a wrapper around those and/or write simple 2-3 line programs to emulate these commands. So I spent half an hour in front of the computer and created these basic commands. Although they are not a very good replacement for the real Unix environment, I guess it was good enough for that 10 year old boy's assignment. So here I am sharing these small utilities.

Using the Code

After I was done with this small exercise, the status of commands was:

ls     - Implemented simple optionless
cd     - Not Implemented as it exist in windows too
pwd    - Implemented
mkdir  - Not Implemented as it exist in windows too
rmdir  - Not Implemented as it exist in windows too
cp     - Implemented
mv     - Implemented
rm     - Implemented
cat    - Implemented
more   - Implemented (windows has its own version but ours will work along with that)
grep   - Implemented
whoami - Implemented
ps     - Implemented (optionless)

So let us look at the small code snippets written for these tiny programs.

ls

static void Main(string[] args)
{
    if (args.Length == 0)
    {
        DirectoryInfo dir = new DirectoryInfo(Directory.GetCurrentDirectory());

        foreach (DirectoryInfo d in dir.GetDirectories())
        {
            Console.WriteLine("{0, -30}\t directory", d.Name);
        }

        foreach (FileInfo f in dir.GetFiles())
        {
            Console.WriteLine("{0, -30}\t File", f.Name);
        }
    }           
}

pwd

static void Main(string[] args)
{
    Console.WriteLine(Directory.GetCurrentDirectory());
}

cp

static void Main(string[] args)
{
    if (args.Length != 2)
    {
        Console.WriteLine("The syntax of the command is incorrect.");
    }
    else
    {
        if (File.Exists(args[0]) == false)
        {
            Console.WriteLine("Source file not found");
        }
        else if (Directory.Exists(args[1]) == false)
        {
            Console.WriteLine("Target Directory not found");
        }
        else
        {
            File.Copy(args[0], args[1] + "\\" + args[0]);
        }
    }
}

mv

static void Main(string[] args)
{
    if (args.Length != 2)
    {
        Console.WriteLine("The syntax of the command is incorrect.");
    }
    else
    {
        if (File.Exists(args[0]) == false)
        {
            Console.WriteLine("Source file not found");
        }
        else if (Directory.Exists(args[1]) == false)
        {
            Console.WriteLine("Target Directory not found");
        }
        else
        {
            File.Move(args[0], args[1] + "\\" + args[0]);
        }
    }
}

rm

static void Main(string[] args)
{
    if (args.Length != 1)
    {
        Console.WriteLine("The syntax of the command is incorrect.");
    }
    else
    {
        if (File.Exists(args[0]) == false)
        {
            Console.WriteLine("File not found");
        }
        else
        {
            Console.WriteLine("Are you sure you want to delete {0} (y/n)", args[0]);
            ConsoleKeyInfo key = Console.ReadKey();
            if (key.Key == ConsoleKey.Y)
            {
                File.Delete(args[0]);
                Console.WriteLine("\nFile Deleted: {0}", args[0]);
            }
        }
    }
}

cat

static void Main(string[] args)
{
    if (args.Length != 1)
    {
        Console.WriteLine("The syntax of the command is incorrect.");
    }
    else
    {
        if (File.Exists(args[0]) == false)
        {
            Console.WriteLine("File not found");
        }
        else
        {
            string contents = File.ReadAllText(args[0]);
            Console.Write(contents);
        }
    }
}

more

class Program
{
    static void Main(string[] args)
    {
        Process.Start("cat " + args[0] + " | more");
    }
}

grep

static void Main(string[] args)
{
    if (args.Length != 2)
    {
        Console.WriteLine("The syntax of the command is incorrect.");
    }
    else
    {
        if (File.Exists(args[1]) == false)
        {
            Console.WriteLine("File not found");
        }
        else
        {
            string[] lines = File.ReadAllLines(args[1]);

            foreach (string line in lines)
            {                        
                if(line.Contains(args[0]))
                {
                    Console.WriteLine(line);
                }
            }
        }
    }
}

whoami

static void Main(string[] args)
{
    Console.WriteLine(Environment.UserName);
}

ps

static void Main(string[] args)
{
    Process[] mYProcs = Process.GetProcesses();

    Console.WriteLine("-----------------------------------------------------");
    Console.WriteLine("{0, -8} {1, -30} {2, -10}", "PID", "Process Name", "Status");
    Console.WriteLine("-----------------------------------------------------");

    foreach (Process p in mYProcs)
    {
        try
        {
            Console.WriteLine("{0, -8} {1, -30} {2, -10}", p.Id, 
            p.ProcessName, p.Responding ? "Running" : "IDLE");
        }
        catch (Exception)
        {
            continue;
        }
    }
}

NOTE: Check out the source code for implementation.

IMPORTANT: The folder that contains these commands should be added in the PATH environment variable.

Points of Interest

At the end of this exercise, I thought about what I did and the only thing I could think of is that perhaps I should have used C++ to implement these commands. That way, I could relieve the users from the burden of having the .NET runtime on their system. But since it solved my purpose, I didn't spend much time on it later. Perhaps, when I get time, I would like to do some more things like:

  • Having all the Unix commands implemented and not just these few
  • Write similar programs in C++
  • Perhaps write the wrappers for Unix like system calls to work on Windows

I will get to these activities once I get some free time from my "real" job.

History

  • Version 1: Basic Unix commands implementation

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rahul Rajat Singh
Software Developer (Senior)
India India
Member
I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems.
 
Some CodeProject Achievements:
  • 9th in Best Web Dev article of March 2013
  • 7th in Best Web Dev article of January 2013
  • 2nd in Best C# article of December 2012
  • 5th in Best overall article of December 2012
  • 5th in Best C# article of October 2012
  • 4th in Best Web Dev article of September 2012
  • 3rd in Best C# article of August 2012
  • 5th in Best Web Dev article of August 2012
  • 5th in Best Web Dev article of July 2012
  • 3rd in Best Overall article of June 2012
  • 2nd in Best Web Dev article of June 2012
  • 5th in Best Web Dev article of May 2012
  • 6th in Best Web Dev article of April 2012
  • 4th in Best C++ article of April 2012
  • 5th in Best C++ article of March 2012
  • 7th in Best Web Dev article of March 2012
  • 5th in Best Web Dev article of February 2012
  • 7th in Best Web Dev article of February 2012
  • 9th in Best Web Dev article of February 2012
  • 5th in Best C++ article of February 2012

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 3memberStephan Clark14 Feb '12 - 3:03 
GeneralMy vote of 1mvpManfred R. Bihy14 Feb '12 - 0:31 
GeneralMy vote of 4memberbigscout7913 Feb '12 - 6:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 8 Feb 2012
Article Copyright 2012 by Rahul Rajat Singh
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid