-
Notifications
You must be signed in to change notification settings - Fork 0
Module 2: Bash Basics for MRI Neuroimaging
Audience: Undergraduate students with zero experience using terminals, command lines, or Bash.
Goal: Build a practical foundation for MRI neuroimaging work (Linux/HPC workflows, BIDS datasets, running pipelines, reading logs, and scripting safely).
- Type commands exactly as shown inside code blocks.
-
Do not type the leading
$if you see it in examples; it represents the prompt. - After most sections, there is a checkpoint. If you can do it, you’re on track.
Time estimates are approximate. If you are brand new, expect closer to 60 minutes.
You can do this tutorial on any of the following:
-
macOS Terminal
Open Terminal (Applications → Utilities → Terminal). -
Windows (WSL Ubuntu)
Open Ubuntu in Windows Subsystem for Linux (WSL). If you do not have WSL, use your course server/HPC option below. -
University server/HPC terminal (web portal)
Use the provided web terminal (often via Open OnDemand or similar). If you are on an HPC, do your practice in your home directory.
What you should see: a window with a cursor where you can type commands.
A prompt might look like:
student@machine:~$
-
studentis your username. -
machineis the computer/server name. -
~means “your home directory”. -
$indicates you are a normal user (not an administrator).
A typical command looks like:
command options arguments
Example:
ls -lah data-
lsis the command. -
-lahare options (also called flags). -
datais an argument (a folder name).
Many terminal actions (especially deletion) do not go to a recycle bin.
my file.txt is treated as two separate words. To include a space:
- Quote it:
"my file.txt" - Or escape the space:
my\ file.txt
If you are not sure what a command does, stop and check its help first:
command --helppwdWhat it does: prints the full path of your current directory.
lsWhat it does: lists files and folders in the current directory.
Common options (you will use these a lot):
ls -l-
-l(long): shows extra details (permissions, owner, size, date).
ls -a-
-a(all): includes “hidden” items (names starting with.).
ls -h-
-h(human-readable): makes sizes easier to read (e.g.,1K,2M,3G).
Note:-hmatters most when combined with-l.
A very common combination:
ls -lah-
-llong format -
-aall (include hidden) -
-hhuman-readable sizes
whoamiWhat it does: prints the account name you are logged in as.
Run:
pwd
ls -lah
whoamiYou should be able to say, in plain English, what each output line means.
cdWhat it does: moves you to your home directory.
cd ~What it does: also moves you to your home directory (~ is a shortcut for home).
cd /What it does: moves you to the filesystem root directory (/).
-
Absolute path: starts with
/(example:/home/student/data) -
Relative path: does not start with
/(example:data), and is interpreted from where you are now.
. means “this directory”
.. means “parent directory” (one level up)
Try:
pwd
cd ..
pwdWhat it does: cd .. moves you up one level in the directory tree.
cd -What it does: returns you to the directory you were in immediately before the last cd.
Do this sequence and explain each step:
cd ~
pwd
cd ..
pwd
cd -
pwdWe will create a folder for this tutorial in your home directory.
cd ~
mkdir -p bash_mri_tutorial
cd bash_mri_tutorial
pwd-
mkdir NAMEcreates a new directory. -
-pmeans “parents”: create any missing parent directories, and do not error if it already exists.
Now create common neuroimaging-style subfolders:
mkdir -p data scripts results
ls -lahecho "hello"What it does: prints text to the screen.
Redirection sends text into a file.
Create a small CSV (comma-separated values) file:
echo "subject_id,session,run" > participants.csv
echo "sub-001,ses-01,run-01" >> participants.csv
echo "sub-002,ses-01,run-01" >> participants.csv-
>writes to a file and overwrites it if it already exists. -
>>appends to the end of a file (adds more lines).
cat participants.csvWhat it does: prints the full file to the terminal.
less participants.csvInside less:
- Press
qto quit - Press
/then type a word to search, then press Enter
You should be able to answer:
- What is the difference between
>and>>? - When should you use
lessinstead ofcat?
cp participants.csv data/What it does: copies participants.csv into the data/ directory.
mv participants.csv data/participants_original.csvWhat it does: moves the file and renames it.
Safer practice for beginners:
rm -i data/participants_original.csv-
-imeans “interactive”: asks you to confirm before deletion.
What it does: deletes the file if you confirm.
Explain what each command does:
cp file1 data/
mv file1 file2
rm -i file2Neuroimaging datasets often contain many similarly named files. Bash helps you match file patterns.
Create MRI-like filenames:
touch data/sub-001_ses-01_T1w.nii.gz
touch data/sub-001_ses-01_task-rest_bold.nii.gz
touch data/sub-002_ses-01_T1w.nii.gz
touch data/sub-002_ses-01_task-rest_bold.nii.gzNow list them:
ls -lah datals data/*.nii.gzWhat it does: lists all files in data/ that end with .nii.gz.
ls data/*T1w*What it does: lists files containing the text T1w anywhere in the name.
ls data/sub-00?_ses-01_T1w.nii.gzWhat it does: matches sub-001 and sub-002 (and would also match sub-003 if it existed).
Predict (before running) what each will list:
ls data/*bold*
ls data/sub-00?_ses-01_task-rest_bold.nii.gzCreate a subject list:
echo -e "sub-001\nsub-002\nsub-010" > data/subjects.txt-
echo -eenables interpretation of\nas “new line”. -
>writes a new file (overwrites if it already exists).
View it:
cat data/subjects.txtSearch for a pattern:
grep "sub-002" data/subjects.txtWhat it does: prints any lines that contain sub-002.
Useful options:
grep -n "sub" data/subjects.txt-
-nprints line numbers.
grep -i "SUB-002" data/subjects.txt-
-iignores case (upper/lowercase treated the same).
A pipe takes the output of one command and sends it into another.
ls data | grep "T1w"-
ls datalists filenames indata/. -
|sends those filenames intogrep. -
grep "T1w"keeps only lines containingT1w.
head -n 2 data/subjects.txt-
headshows the first lines. -
-n 2means “show 2 lines”.
tail -n 2 data/subjects.txt-
tailshows the last lines.
Explain what this does, step by step:
ls data | grep "sub-001" | grep "bold"wc -l data/subjects.txt-
-lcounts lines.
This is common in neuroimaging to confirm how many subjects/runs you have.
Many commands quietly indicate success/failure. You can check the last command’s exit status:
echo $?-
0typically means success. - Any non-zero value typically means some kind of error.
Try:
grep "sub-999" data/subjects.txt
echo $?grep will find nothing, and the exit status is usually non-zero.
Explain why wc -l is useful when you have a subject list.
Neuroimaging pipelines often need to locate files inside nested folders.
First, create a BIDS-like folder structure (simplified):
mkdir -p data/bids/sub-001/ses-01/anat
mkdir -p data/bids/sub-001/ses-01/func
mkdir -p data/bids/sub-002/ses-01/anat
mkdir -p data/bids/sub-002/ses-01/funcCreate placeholder files:
touch data/bids/sub-001/ses-01/anat/sub-001_ses-01_T1w.nii.gz
touch data/bids/sub-001/ses-01/func/sub-001_ses-01_task-rest_bold.nii.gz
touch data/bids/sub-002/ses-01/anat/sub-002_ses-01_T1w.nii.gz
touch data/bids/sub-002/ses-01/func/sub-002_ses-01_task-rest_bold.nii.gzfind data/bids -type f -name "*T1w.nii.gz"-
find data/bidstellsfindwhere to start searching. -
-type fmeans “files” (not directories). -
-name "*T1w.nii.gz"matches filenames ending inT1w.nii.gz. - The
*inside quotes is a wildcard for the name pattern.
Limit the search depth (optional but useful):
find data/bids -maxdepth 5 -type f -name "*.nii.gz"-
-maxdepth 5stops searching deeper than 5 directory levels.
Write a find command that lists only *bold.nii.gz files under data/bids.
Variables reduce mistakes by keeping important paths in one place.
Set a variable:
BIDS_DIR=~/bash_mri_tutorial/data/bids
echo $BIDS_DIR-
BIDS_DIR=...assigns a value. -
No spaces around
=. -
$BIDS_DIRreads the variable’s value.
Use it:
ls -lah "$BIDS_DIR"Why the quotes?
-
"$BIDS_DIR"is safer if the path contains spaces.
Common neuroimaging variables you will see:
-
BIDS_DIR(raw dataset root) -
DERIV_DIR(derivatives output root) -
SUBJECTS_DIR(FreeSurfer subjects directory)
Set:
DERIV_DIR=~/bash_mri_tutorial/results/derivativesThen create it using mkdir -p "$DERIV_DIR".
This section simulates what real pipelines do:
- read a subject list
- make per-subject output folders
- write logs
Create output/log directories:
mkdir -p results/qc results/logsRun a loop:
while read -r SUBJ; do
echo "Processing $SUBJ"
mkdir -p "results/qc/$SUBJ"
echo "QC placeholder for $SUBJ" > "results/qc/$SUBJ/qc.txt"
echo "$(date): finished $SUBJ" >> results/logs/pipeline.log
done < data/subjects.txtExplain each part:
-
while read -r SUBJ; do ... done < data/subjects.txt
Reads the filedata/subjects.txtline-by-line. Each line goes into the variableSUBJ. The-roption prevents backslash escaping issues. -
echo "Processing $SUBJ"
Prints a progress message. -
mkdir -p "results/qc/$SUBJ"
Creates an output directory for that subject. -
echo "QC placeholder for $SUBJ" > "results/qc/$SUBJ/qc.txt"
Writes a per-subject QC text file (overwrites if it exists). -
echo "$(date): finished $SUBJ" >> results/logs/pipeline.log
Appends a timestamped log line.$(date)runs thedatecommand and inserts its output.
Check results:
find results -type f -name "*.txt"
tail -n 5 results/logs/pipeline.logOpen one QC file using cat:
cat results/qc/sub-001/qc.txtThen explain where the file path came from.
In real neuroimaging, you do not want to retype long commands every time. You put them in scripts.
Create a script file:
cat > scripts/hello_mri.sh << 'EOF'
#!/usr/bin/env bash
echo "Hello from a Bash script."
echo "Working directory: $(pwd)"
echo "BIDS files:"
find data/bids -type f -name "*.nii.gz"
EOFExplain the pieces:
-
cat > scripts/hello_mri.sh << 'EOF'
Starts writing text intoscripts/hello_mri.sh. The<< 'EOF'part is a here-document: everything untilEOFis written into the file. Quoting'EOF'prevents variable expansion while writing. -
#!/usr/bin/env bash
Called a shebang. Tells the system to run the script using Bash.
Make it executable:
chmod +x scripts/hello_mri.sh-
chmodchanges permissions. -
+xadds “execute” permission.
Run it:
./scripts/hello_mri.sh-
./means “run the file in the current directory”.
Edit the script so it prints your subject count using:
wc -l data/subjects.txtThen rerun the script.
Most commands have manuals.
man ls- Use arrow keys to scroll.
- Press
qto quit.
Also common:
ls --helpThis prints a short help summary.
After this tutorial, you should recognize what these kinds of commands mean (examples only):
recon-all -subjid sub-001 -i sub-001_T1w.nii.gz -all- Runs a FreeSurfer pipeline for a subject.
fslmaths input.nii.gz -mas mask.nii.gz output_masked.nii.gz- Uses FSL to apply a mask.
python scripts/run_qc.py --bids "$BIDS_DIR" --out "$DERIV_DIR"- Runs a Python QC script using dataset/output variables.
You are not expected to understand these tools yet. You are expected to be comfortable with:
- paths
- file patterns
- loops
- logs
- scripts
Do this without copying from earlier sections.
- Create a new folder:
~/bash_mri_tutorial_practice
- Inside it, create:
data/results/scripts/
-
Make a subject list with three subjects in
data/subjects.txt. -
Write a loop that creates:
results/<subject>/qc.txt
and appends a timestamped line into:
results/pipeline.log
- Use
findto verify your output files exist.
If you can do this, you have enough Bash to start real MRI workflows safely.
pwd
ls -lah
cd PATHmkdir -p DIR
cp SRC DST
mv SRC DST
rm -i FILEgrep -n "pattern" FILE
find ROOT -type f -name "*.nii.gz"
while read -r X; do ...; done < list.txt