Sharing bash functions between scripts

I’ve spent most of the past week writing bash functions to help with automating build and deployment at work, and something I’ve never really paid much attention to is how to keep these .sh files structured. Trying to keep functions small and generic helps with reuse and saves me from having to write more code, and once I’ve tested something is working hopefully I won’t need to touch it again.

To quote the first item of the summarised Unix philosophy:

Write programs that do one thing and do it well.

It’s also made me think about another horrible mess of code that I’ve come to depend on, my .bash_aliases file.

This has truly become a dumping ground over the years to save me from having to remember almost everything I have done at one point or another. At what I feel is a whopping 1474 lines, my little black book of functions is something that I lean on a lot, but have never really taken any time to trim or polish, apart from some headings in the form of comments.

Creating some structure

So the first step in organising this mess is trying to group similar functions together. Near the very top of my .bash_aliases file I find this:

##########  Git aliases ##################
alias gs='git status'
alias ga='git add'
alias gd='git diff'
alias gc='git commit'
alias gca='git commit -a'
alias gb='git branch'
alias gbr='git branch --remote'

So there are some aliases that I use because I’m lazy, and shaving off those extra keystrokes should save some wear and tear on my little digits. I’ve already noted in the file what this group applies to GIT so that is a great starting point.

Let’s create a new directory to store my newly structured files:
mkdir ~/scripts
There’s a new directory in my home directory called scripts. Next is to copy and paste the contents from .bash_aliases to a new file called within this folder.

Setting up the files

I could just copy and paste the contents in Emacs, but where’s the fun in that. I can use sed to grab the lines that I want and output them to this new file without having to leave the terminal.

sed -n '19,27p' ~/.bash_aliases > ~/scripts/

So here we are using sed to get the line between 19 and 27 from the file ~/.bash_aliases and outputting them to the file ~/scripts/ easy. Bash files should have the following at the top ‘#!/bin/bash’, to tell the OS which interpreter should be used for the file. This way seems slightly hacky, but again, means I don’t need to leave the terminal.

sed -i '1s:^:#\!/bin/bash\n:' ~/scripts/

This sed command inserts the required text on the first command, followed by a new line, giving us what we want.

Next we need to delete the text from .bash_aliases. Again, let’s stay in the terminal, we’ve almost written the command we need already.

sed -n '19,27d' ~/.bash_aliases

So, sed lessons are over (almost), our files are set up and I’ll try and get this post back on track.

If we were to open a terminal at this point, the commands we’d receive a command not found message. This can easily be fixed, and I’m going to use sed again because why not?

sed -i '2s:^:\n\. ~/scripts/git\.sh\n\n:' ~/.bash_aliases

Here we are inserting a new line to our .bash_aliases file using the . command to source the contents of our file. Because .bash_aliases is run every time we open a bash shell, we now have contents of the ~/scripts/ available at all times, whilst also keeping our git alias code separate.

I’ve got lots of functions that can be grouped together, so I envisage creating a file,, file and many others in the future.

Repeating this over the coming months should really help whip my .bash_aliases file into shape.


So this post devolved into a post about the Power of sed rather than what it was initially supposed to be, but the TD;DR is that:

1) massive files are bad
2) the . command will source or import code from another file
3) grouping similar functions into separate files helps make navigation of code easier
4) with the . command we can share code between files without repeating ourselves
5) we can use sed to manipulate text files succinctly, precisely with a couple of keystrokes

If you’ve made it this far, thanks for reading.

Using variables in strings in C#

Strings are great. Letters, numbers and symbols, all at the same time?


Soon enough hard coded strings aren’t going to cut it and you’ll want them to be more dynamic.

Below are 3 methods of mixing variables with your strings:

The Concat Operator +

The + operator when used on string variables will allow you to join them together.

So given the variables firstName and lastName, we could join them together like so:

string firstName = "Frank";
string lastName = "Castle";
string fullName = firstName + lastName;

If you run this example your output will be “FrankCastle”.

Unfortunately this doesn’t give us exactly what we want.

To add a space to separate the names, update your code to the following:

string firstName = "Frank";
string lastName = "Castle";
string fullName = firstName + " " + lastName;

This will output “Frank Castle”. Exactly what we want.

As you can see, we’ve added an extra string in between the 2 variables with no characters, just a single space.

For those unfamiliar, Frank Castle has an alias, let’s add that in between his firstName and lastName for full effect.

string firstName = "Frank";
string lastName = "Castle";
string fullName = firstName + " 'The Punisher' " + lastName;

The output will be: “Frank ‘The Punisher’ Castle”.

Something to note is we’ve used (single quotes) rather than (double quotes) purposefully, so we don’t need to worry about “escaping” the double quotes. I’ll cover that in a future post.

Just to reiterate, we could have used the following to get our fullName variable, but we lose the flexibility and context that our variable names provide:

string fullName = "Frank" + " 'The Punisher' " + "Castle";


.Net comes with lots of handy functionality built in. The String.Format() function helps simplify string concatenation by allowing us to define how we want the output string to be structured, and then pass in the variables to use as argument after.

In order to achieve the output from our previous example we can use the following code:

string firstName = "Frank";
string lastName = "Castle";
string fullName = String.Format("{0} {1}", firstName, lastName);

The output again will be: “Frank Castle”.

To explain what is happening, the Format function is taking 3 arguments, the first is a string, the second and third are our variables. In the format string we are defining where we want our variables to be in the output string. {0} is our firstName argument, and {1} is our lastName argument. The reason we access them as 0 and 1 and not as 1 and 2 as you might expect is because in C# we use zero-based numbering. You will come across this when you use loops, arrays and lists. What it means to us is that our first item is located at position 0 and our second is at position 1.

Something nice is that we can now easily move our variables. If we wanted the output to read “Castle Frank”, we can do the following:

string firstName = "Frank";
string lastName = "Castle";
string fullName = String.Format("{1} {0}", firstName, lastName);

By swapping the index values our output string displays as expected.

We can also duplicate values by repeating their index. To get the output string “Frank Frank Castle” we do the following:

string firstName = "Frank";
string lastName = "Castle";
string fullName = String.Format("{0} {0} {1}", firstName, lastName);

Something else to be aware of is we can add in extra text as we please. To give Frank his full title, we just need:

string firstName = "Frank";
string lastName = "Castle";
string fullName = String.Format("{0} 'The Punisher' {1}", firstName, lastName);

We are still using single quotes so we don’t have to do any “escaping”.

String Interpolation

Saving the best ’til last, string interpolation. We get the simplicity offered by String.Format() and the clarity from the concatenation operator.

By simply adding a $ in front of our first double quote, we can use our variables by name. Our 3 example from above are reflected below:

string firstName = "Frank";
string lastName = "Castle";
string fullName = "{firstName} {lastName}";

Outputs: “Frank Castle”

string firstName = "Frank";
string lastName = "Castle";
string fullName = $"{firstName} {firstName} {lastName}";

Outputs: “Frank Frank Castle”

string firstName = "Frank";
string lastName = "Castle";
string fullName = $"{firstName} 'The Punisher' {lastName}";

Outputs: “Frank ‘The Punisher’ Castle”


By now this code should make sense and you should understand each method and be able to find one which suits your situation.

In practice I only use string interpolation now, but it is good to know what options are available, and forget the ones you don’t need.

An honourable mention is the StringBuilder class, which offers increased performance when dealing with lots of concatenations, and is probably worth another post in itself.

That wraps up the first post in my series for beginners, hopefully it has been useful.

More Reading

If you’d like some more information on how the + operator works see this StackOverflow answer for more details.