- Not all of us have those over priced fancy fruit laptops that some developers are so gung-ho about 🥊.
- Some of us actually need to get work done in a reasonable amount of time without having to recompile our OS kernels or looking for the right program made for our distribution of Linux only to find out that the instructions don’t work and then spend hours sifting through forum posts by *nux trolls 🥊.
- Now that I have alienated myself from the Linux and Mac communities, that just leaves us shlubs, the developers who use Windows as our operating system. Hello! 👋 this article is for you!
Shhh, I just want the answer
You can skip all of my ramblings. Just scroll to the bottom for the code or click here.
I do recommend reading some of this if you need perspective on why shell scripting is so important right now to developers on Windows. It’s always been important, but now it’s essential.
Our worlds are melding
It’s undeniable that as time moves forward, our programming worlds are colliding together between people who are using Windows versus Mac, Linux, Unix etc… (going to just call this Nux for simplicitly). Frankly, I don’t care which operating system you use, just don’t be an asshole 😁. All too often I see anti-Microsoft and anti-Windows sentiment in forum posts and it really upsets me. I am not going to get into that flame war here about this subject, but my point is – Don’t shame others for what they use – unless it’s VB-like languages because VB is very bad. All joking aside, we are all developers, just help each other out and leave ego out of it. Especially if it someone who is trying to stop using VB, they need the most help ❤️.
I think it’s fair to say that Git has won the industry over by storm as being the defacto source control to use. Who knows, maybe this will change eventually as being someone who was using Visual Source Safe and TFS(VC) since 2008. I love Git – it’s leaps and bound better than SVN and TFS-VC in my opinion. That being the case, it was time to start learning how to use all of the git commands under the sun. Eventually, ideas of automation are concieved and programs start being written to automate manual work to prepare for releases. I think git-bash is awesome, but recently I started using cmder and I am in love with it. I hardly open up CMD anymore unless I absolutely need to and I avoid PowerShell as much as I can because the syntax frankly is horrific.
Developers on Windows and CLI
The point is I am sure many developers on Windows OS are gradually moving over to Nux driven/based technologies such as but not limited to:
- Windows Linux Sub System – running Ubuntu locally with access to bash
- Containers – Docker for Windows
- dot net core, dot net 6, dot net 7 and beyond with focus of running in Linux containers
- NodeJs / NPM / Yarn
One thing all of these things have in common is CLI is at the center of making most of it work. Whether it is via shell scripts, YAML or whatever – a CLI is being used to drive everything. To be clear, Windows does this too, but doesn’t burden the end user with it normally. Unfortunately, that makes Windows users too heavily reliant on all-in-one “don’t ask me anything” installers and “Gimme a GUI or I don’t know what to do”. This is why I have big respect for anyone who programs in C/C++ on a Nux system, they are very in-tune with their technology. However, one thing I have noticed about Nux systems is it can become too cumbersome at times to have to run a twenty five commands and remembering all of the syntax, especially when something doesn’t work as expected. Sadly, the answer to that is more scripting and this is where we part ways, I want a UI at that point. I just want to do my job, not get get buried in the details of how to get my framework to build.
Shell scripts in Windows
Anyone who is a developers working in Windows just needs to start to understand how Nux works. This isn’t that difficuilt to start to do, of course the individual parts can become overwhelming, but that’s where practice comes in. You can quickly identify if a Nux like thing will work in Windows by opening up CMD and attempting to run it. Of course, you need to be cognizant of what is in your
PATH environment variable already.
For example if you attempt to run
bash in Windows you should expect to see this error:
'sh' is not recognized as an internal or external command, operable program or batch file.
In other words, don’t expect a Nux native program to exist on Windows. That’s a losing battle. Strangely enough if I just run
bash – nothing happens. I don’t get an error, but I also cannot run shell scripts, so it’s not working as far as I am concerned.
For some people, it’s simple enough to just update their
PATH environment variable to include
bash, but this falls apart if you need to share a program with others that depends on executing a shell script. Therefore, you just need to bend your thinking a little. Since everyone pretty much uses
git now, that means they should have
git-bash installed locally. This is an okay assumption to make and frankly asking people to install
git isn’t a big deal either.
I am not saying this solution is a magic bullet for every shell scripting need, but it will cover you for
git commands at the very minimum. I want to say it will cover you for
grep too, but I am not totally sure yet (but it should). My thinkin is, that if you can execute it from git-bash, then you are safe to write a shell script and execute it from C# using git-bash. This is not the most elegant solution, but it does work.
Execute shell scripts with git-bash from System.Diagnostics.Process in C#
The only thing I don’t like about this approach is that it will open up a visible git-bash window during execution 😠, but hey at least it works 🤷♂️.
You can execute shell scripts using git-bash like so:
using var p = new Process();
var s = p.StartInfo;
s.UseShellExecute = false;
s.RedirectStandardOutput = true;
s.CreateNoWindow = true;
s.FileName = "C:\Program Files\Git\git-bash.exe"; //Using GitBash to do the dirty work
s.Arguments = "C:\dev\scripts\some-script.sh";
p.ErrorDataReceived += (_, args) => Console.WriteLine(args.Data);
var stdOutput = new StringBuilder();
p.OutputDataReceived += (_, args) =>
var output = stdOutput.ToString();
This code example has a tough time outputting anything useful on the screen. I am still trying to figure that out, but it does perform the execution which is the most important part. For context this is an example of what I am executing from
ECHO fetching for "Project A"
git fetch --all
git log origin/master..origin/develop --no-merges --format="%h|%an|%ai|%cn|%ci|%s" > "C:\dev\_output\ProjectA.txt"
This is an excerpt of a larger script which is going to several repositories:
- Changing directory to the target repository where the
.gitfolder is located.
- Performing a fetch to update local meta data.
- Performing a
- Finally writing that output to a flat file so it can be consumed elsewhere.
I would also like to point out, that originally I was trying to execute a shell script via batch file (*.bat) thinking that would make a difference somehow. In reality it was still CMD attempting to execute
sh. I confused myself because I was using cmder for the execution during testing, not realizing that cmder had tooling for this built in. Windows does not.
This took a lot of toiling to do. I reviewed so many posts and articles just to get to this conclusion. I hope that since Windows is already in bed with Nux, they should seriously just pull the bandaid off and give us bash by default with all of the tools you would normally find in a Nux distribution. Until then, I strongly recommend using git-bash and cmder which are both awesome tools. Cmder has changed the way I work now since it has so many tools built in.
These are all of the pages that helped me make this happen. I took inspiration from a bunch of different posts. Most of which were for different purposes, but the main idea is what helped me get to this conclusion.
- This is the link that really solidified the idea for me