Things covered here:
- Introduction to CLIMB
- Exercises to recap Bash
Although your MacBooks run a version of Unix, most bioinformaticians prefer to use Linux and so most programs and pipelines work best on Linux. In bioinformatics, most researchers also prefer to use remote virtual servers over their own personal (bare metal) machines for several important reasons:
We will be using a Jupyter notebook server, which is an easy-to-access web-based platform that allows users to create and interact with Jupyter Notebooks, which in turn are documents that can contain live code, equations, visualizations, and text. The server runs the computational backend that provides command line access to a Linux shell, but can also processes code cells written in languages like Python, R, or Julia, and returns the output to the browser interface where users can view and manipulate results.
Before we get stuck in to using a Notebook server, let’s set the scene with a short Powerpoint presentation
The terminal allows us to access a system shell (just like on your MacBooks), so let’s start there.
Select File -> New -> Terminal, or click the Terminal icon on the launcher pane. You’ll get a new terminal tab in the activity bar, and find yourself in a bash shell.
Looking at your bash prompt, you’ll notice that your username is jovyan (derived from “Jupyter”). Why does everyone have the same username in this environment? That’s because your notebook server is running inside a container. Containers are lightweight, self-contained environments that bundle an application (in this case, the Jupyter notebook server) together with its dependencies, ensuring that it runs consistently across different systems.
The container instance is private and linked to your specific user storage on the system, but the actual image (which includes the software, configurations, and libraries) is the same for everyone using the platform. This is why it’s unnecessary to have unique system users for each individual—everyone operates within the same standardized environment, hence the shared username.
A container is a technology that allows you to package up an application, along with all of its dependencies, libraries, and configurations, into a single isolated environment. This guarantees that the application runs consistently, no matter where it’s deployed. Unlike virtual machines, which simulate an entire operating system, containers are more lightweight because they share the host system’s kernel, making them faster and less resource-intensive.
In a Jupyter Notebook server context, containers allow multiple users to have their own private instances, even though they all use the same underlying software image. This ensures consistency across users, simplifies deployment, and provides isolation—what happens in your container doesn’t affect others. It’s a key technology in environments where reproducibility and ease of scaling are important, like in data science and bioinformatics workflows.
TLDR: Don’t worry about it! Inside your notebook server, everyone’s username is set to jovyan because you’re working inside a standardized container environment that provides all the necessary tools and libraries for your Jupyter notebooks.
By default, you’re in a bash shell running against the base operating system of the climb-jupyterhub container image (which is based on a flavour of Linux called Ubuntu). You’ll see in your bash prompt that you’re in your home directory (represented by the tilde character ~).
jovyan:~$ pwd
/home/jovyan
sudo hereOne Unix command that you cannot use on this Notebook server is sudo. Try it
sudo touch file.txt
jovyan doesn’t have sudo privileges. This may seem restrictive, but we’ve pre-configured the climb-jupyter base image with everything you’d likely need sudo for pre-installed. Everything else should be installable via package managers, such as Conda, which we are going to learn more about after coffee.
Within the Terminal here, you can do almost all the things we did yesterday using Unix on your MacBooks.
TASKS 1. Write a for loop that prints each of these species names, one per line:ecoli,salmonella,klebsiella,campy.2. Write a for loop that prints the name of each file inSolution
for species in ecoli salmonella klebsiella campy do echo $species done
~/shared-team/2026_training/week1/unix_intro/gene_annotations/.
Hint: try using*to match all files in the folder.3. Modify your loop so that for each file it also prints how many lines it has.Solution
for file in ~/shared-team/2026_training/week1/unix_intro/gene_annotations/* do echo $file done
Hint:wc -lcounts lines in a file.4. Add a preview of the first line of each file to your loop.Solution
for file in ~/shared-team/2026_training/week1/unix_intro/gene_annotations/* do echo $file wc -l $file done5. Put your loop into a script calledSolution
For TSV files, the first line is usually the column headers, so this gives you a quick idea of what each file contains.for file in ~/shared-team/2026_training/week1/unix_intro/gene_annotations/* do echo $file wc -l $file head -n 1 $file donesummarise_dir.shand run it.6. Make your script executable so you can run it withSolution
Open a new file with nano:Type in your loop, save withnano summarise_dir.shCtrl+O, and exit withCtrl+X. Then run it:bash summarise_dir.sh./summarise_dir.shinstead of
bash summarise_dir.sh.
Hint: you need two things: a shebang line at the top of the script, and the right file permissions.7. Modify your script so it takes a folder as an argument instead of always checking the same folder.Solution
Add#!/bin/bashas the first line of the script, then:chmod +x summarise_dir.sh ./summarise_dir.sh
Hint: the first argument passed to a script is available as$1.8. Modify your script so it takes a second argument for an output file, and saves the results there instead of printing to the screen.Solution
Run it with:#!/bin/bash for file in $1/* do echo $file wc -l $file head -n 1 $file doneTry it on a different folder to check it works../summarise_dir.sh ~/shared-team/2026_training/week1/unix_intro/gene_annotations
Hint: the second argument is$2. You already know how to redirect output to a file.9. Add the folder containing your script to your PATH permanently so you can run it from anywhere.Solution
Run it with:#!/bin/bash for file in $1/* do echo $file wc -l $file head -n 1 $file done > $2./summarise_dir.sh ~/shared-team/2026_training/week1/unix_intro/gene_annotations summary.txt cat summary.txt
Hint: add anexport PATH=line to your~/.bashrc.Solution
First, check which directory your script is in:Then edit your .bashrc:pwdAdd this line at the end of the file, using the path to the folder where your script lives:nano ~/.bashrcSave and exit, then restart your terminal or apply it without restarting:export PATH=$PATH:/path/to/your/scriptsEvery new terminal you open will now have this path included automatically. Try changing to a completely different directory and running your script!source ~/.bashrc
This training course was adapted from material develop by Andrea Telatin and Lisa Marchioretto.