--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files
Aims of this training:
This is a 2.5 hour tutorial. We will be trying out what we are learning, so be ready for some typing!
These lecture slides are based on the Software Carpentries documentation on Unix Shell basics, but is a shorter course and uses different examples.
Once you finish this tutorial, we recommend you read through the Software Carpentries material and follow through the tutorial there: you can do this work from the same virtual machine we will be using today.
The aim is not for you to leave knowing loads of Linux Bash commands!
It’s helpful for you as a learner to understand the PRIMM structure so you can apply it while working through this course. Not every step will be relevant or used at every stage of the course!
PRIMM is a pedagogical method specifically aimed at teaching text-based programming. While research into adult programming learners is very limited (especially in terms of demographics; many key studies that are cited have overwhelmingly homogenous test groups), the PRIMM method has a few key benefits:
The P in PRIMM stands for predict:
When you first see a command, script, or piece of code, before running it, predict what you think it will do. It’s ok to get this wrong: the important thing is to get into the habit of predicting! This helps to keep you actively engaged and focused, and begins to build an intuitive sense about the structure of commands.
The R in PRIMM stands for run:
The I in PRIMM stands for investigate:
Let’s dig a little deeper into the structure of code you’ve used.
The first M in PRIMM stands for modify:
This stage helps you to gradually increase the difficultly of the tasks you are doing!
The second M in PRIMM stands for make:
This stage is about making the code your own.
Read before you write - research has proven repeatedly the importance of reading and predicting the output of code as a method of learning, over just getting straight into it and writing code.
Learn in a way that suits you - if that is copying and pasting commands from the slides instead of trying to keep up with typing, that’s ok!
When we use a computer, we interact with the hardware through an operating system or OS.
Common operating systems for research computers include:
We are going to be looking at Linux today, which is a family of operating systems that are Open Source and are widely used in research, for example on High Performance Computing platforms like ARC4 or Aire.
When we use a computer, like our desktop or laptop, we often use a Graphical User Interface or a GUI.
As well as using a GUI, we can also interact with computers using a Command Line Interface or a CLI.
Throughout this presentation, we will be using quick polls to gauge your familiarity with concepts.
Let’s test it out:
How do we access Bash?
We’re going to use a virtual machine for this course: this is a Linux machine running in the cloud.
This means that everyone here can run it with the exact same set-up; you only need a browser.
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files
Each rectangle is a folder or directory (dir for short)
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files style / fill:#f9f,stroke:#333,stroke-width:10px,color:#333
Each rectangle is a folder or directory (dir for short)
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333
Each rectangle is a folder or directory (dir for short)
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files style my-username fill:#f9f,stroke:#333,stroke-width:10px,color:#333
The my-username
folder is your user home directory
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files style my-username fill:#f9f,stroke:#333,stroke-width:10px,color:#333
How do we describe the address of this home directory?
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files style my-username fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style / fill:#f9f,stroke:#333,stroke-width:10px,color:#333
The folders in the address are /
, home
and my-username
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files style my-username fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style / fill:#f9f,stroke:#333,stroke-width:10px,color:#333
Stick them together like a URL: /home/my-username
On Windows, file paths use backlashes ( \
) instead of forward slashes (/
)!
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--obin / o--odev / o--oetc / o--ohome home o--omy-username home o--omy-friend / o--otmp my-username o--o all_my_files style my-username fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style / fill:#f9f,stroke:#333,stroke-width:10px,color:#333
Stick them together like a URL: /home/my-username
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--ohome home o--omy-username my-username o--o all_my_files style my-username fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style / fill:#f9f,stroke:#333,stroke-width:10px,color:#333
/home/my-username/all_my_files
is a bit long…
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart / o--ohome home o--omy-username my-username o--o all_my_files style my-username fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style / fill:#f9f,stroke:#333,stroke-width:10px,color:#333
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart home["~"] o--o all_my_files style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333
/home/my-username/all_my_files
is a bit long…
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '32px', 'padding': '40px'}}}%% flowchart home["~"] o--o all_my_files style home fill:#f9f,stroke:#333,stroke-width:10px,color:#333
/home/my-username
every time we refer to a directory or file, we can use the shortcut ~
, called a tilde/home/my-username/all_my_files
to ~/all_my_files
Let’s test your familiarity with Linux file paths!
Time to explore some files on a Linux system!
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"])
For this course, we’ve built a custom virtual machine for you to use.
This requires a GitHub account which you were asked to set up before this course.
(Don’t worry if you haven’t - please go and quickly sign up to GitHub now!)
One of the pre-requisites for this course was signing up for an account with GitHub, as this is the service we use to host the virtual Linux machines for teaching this session.
There will be a green button with the word “Code”, which will then bring up a menu when clicked.
↑ Click this button, this menu opens →
Once you’ve launched your virtual machine, you will see a terminal window something like this:
_
_@username → /workspaces/bash-codespaces-template (main) $ ▮
_
_
_@username → /workspaces/bash-codespaces-template (main) $ ▮
_
The underlined section is your directory path.
Once you’ve launched your virtual machine, you will see a terminal window something like this:
_
_@username → /workspaces/bash-codespaces-template (main) $ ▮
_
_
_@username → /workspaces/bash-codespaces-template (main) $ ▮
_
The underlined section has to do with the git version control system: not a topic for today, but you can learn about this in SWD2!
Once you’ve launched your virtual machine, you will see a terminal window something like this:
_
_@username → /workspaces/bash-codespaces-template (main) $ ▮
_
The dollar symbol ($) and rectangle (▮) on the right hand side are the end of the prompt and the cursor.
If you click on the ▮ or the space just to the right of the $ you can type in your message:
_
_@username → /workspaces/bash-codespaces-template (main) $ hello▮
_
Anything you type will be in white text in the terminal; the cursor will blink at the end of the text.
To send the argument or message, you need to press ENTER on your keyboard.
If you click on the ▮ or the space just to the right of the $ you can type in your message:
_
_@username → /folders (main) $ this is the code you type ↵
_
cd
We’re going to use the cd
command to bring us to our home directory.
_
_@username → /folders (main) $ ▮
_@username → /folders (main) $ cd ↵
_@username → ~ $ ▮
_
cd
cd
stands for change directory~
or /home/vscode
_@username → ~ $ ▮
Now that you know how to find home (from wherever in the file system you are), you need to know what’s in your home directory.
ls
ls
to listUsing the ls
command to list out the contents of the directory:
_
_@username → ~ $ ▮
_@username → ~ $ ls ↵
_blue-folder pink-folder red-folder
_@username → ~ $ ▮
_
ls
to listHow do we know if blue-folder
is a file or a directory? (imagine it has a less descriptive name)
_@username → ~ $ ls ↵
_blue-folder pink-folder red-folder
_@username → ~ $ ▮
_@username → ~ $ ls -F ↵
ls
to listWe can use ls -F
: this tells us the category of the “things” in the directory
this/
) then the item is a directory or folder_@username → ~ $ ls -F ↵
_blue-folder/ pink-folder/ red-folder/
_@username → ~ $ ▮
ls
to listThis is what we expected: we saw in our directory map that we have three directories in our home (~
): red-folder
, pink-folder
, and blue-folder
.
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"])
ls
to listLet’s list what’s inside pink-folder
…
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"])
ls
to listWe can use ls name-of-folder
to tell us what’s in a sub-directory.
What will the output be?
_@username → ~ $ ls pink-folder ↵
_pink-file.md pink-subfolder say_hi.sh
ls
to listWe can use ls -F name-of-folder
to tell us what’s in a sub-directory and what category the items are.
What will the output be?
_@username → ~ $ ls -F pink-folder ↵
_pink-file.md pink-subfolder/ say_hi.sh*
/
);*
);Let’s test your familiarity with these commands!
So far, we’ve used:
cd
on it’s own to go to our home directory;ls
on it’s own to list out the contents of our current directory (our home);ls -F
(ls
with the flag or option -F
) to list out the categories of the content in the directory;ls dir-name
(ls
with the argument dir-name
) to list out the content of the sub-directory dir-name
;You’ve already cracked how bash works with these few commands!
_$ ls -F dir-name
cd
We’ve used cd
on it’s own to access our home directory - what happens when we give it an argument?
What will the output be?
_@username → ~ $ cd pink-folder ↵
_@username → ~/pink-folder $ ▮
We’ve moved down our directory structure, into the directory pink-folder
cd
and ls
cd
and no options or argumentsls
to find out what is in the different directoriescd name-of-dir
to move to a subdirectoryclear
command to clean up your terminal screen if it’s getting too messy:_@username → ~ $ clear ↵
There are two different ways of getting information about commands and their options and arguments within the shell:
man arg
arg --help
On our virtual machine, we are going to use the section option, arg --help
. Try running ls --help
:
_@username → ~ $ ls –help ↵
You’ll be faced with a wall of text and will have to scroll to find the top of it:
_@username → ~ $ ls –help ↵
Usage: ls [OPTION]… [FILE]…
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor –sort is specified.
Mandatory arguments to long options are mandatory for short options too.
-a, –all : do not ignore entries starting with .
-A, –almost-all : do not list implied . and ..
and on, and on, and on…
This can be really useful for quickly checking the arguments and options to commands you half-remember, but can also be incredibly unhelpful and overwhelming if you don’t know what you’re looking at!
ls
, wrap it in quotation marks in your search to require it;ls -a
do?
ls --help
?ls -a
inside pink-folder
?_@username → ~/somewhere $ cd ↵ go back to home
_@username → ~ $ cd pink-folder ↵ go to folder
_@username → ~/pink-folder $ ls -a ↵ ???
ls -a
_@username → ~/pink-folder $ ls -a ↵
_ . .. pink-file.md pink-subfolder say_hi.sh .super-secret-hidden-file .super-secret-hidden-folder
_@username → ~/pink-folder $ ls -F -a ↵
_ ./ ../ pink-file.md pink-subfolder/ say_hi.sh* .super-secret-hidden-file .super-secret-hidden-folder/
What’s in these weird directories .
and ..
?
ls .
and ls ..
cd .
and cd ..
pwd
(path to the working directory) to print out exactly where you are (using /home/vscode
instead of ~
)ls -a
What’s in these weird directories
.
and..
?
- Try exploring them with
ls .
andls ..
- Try going to them using
cd .
andcd ..
- You can use the command
pwd
(path to the working directory) to print out exactly where you are (using/home/vscode
instead of~
)
.
stands for the current directory - the place you get when you use pwd
..
stands for the directory above the current directory.~/pink-folder/pink-subfolder
:
.
is the folder ~/pink-folder/pink-subfolder
..
is the folder ~/pink-folder
So far, we’ve looked at absolute paths that start up at ~
or /home/vscode
.
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"])
So far, we’ve looked at absolute paths that start up at ~
or /home/vscode
.
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"]) style A fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style C fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style P1 fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style p4 fill:#f9f,stroke:#333,stroke-width:10px,color:#333
~/pink-folder/pink-sub-folder/helloworld.py
But if we are already in pink-folder
(if it’s our working directory), we can use a relative path:
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"]) style C fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style P1 fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style p4 fill:#f9f,stroke:#333,stroke-width:10px,color:#333
pink-sub-folder/helloworld.py
But if we are already in pink-subfolder
(if it’s our working directory), we can use a relative path:
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"]) style P1 fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style p4 fill:#f9f,stroke:#333,stroke-width:10px,color:#333
helloworld.py
What if we are in pink-subfolder
(if it’s our working directory), and want the path to pink-file.md
?
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"]) style P1 fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style p2 fill:#ff0,stroke:#333,stroke-width:10px,color:#333
Hint: what can we see with ls ..
from the current directory?
What if we are in pink-subfolder
(if it’s our working directory), and want the path to pink-file.md
?
../pink-file.md
--- config: look: handDrawn --- %%{init: {'themeVariables': { 'fontSize': '28px'}}}%% flowchart TD A["/home/vscode/ <br> or ~"] o--o B[red-folder] A o--o C[pink-folder] A o--o D[blue-folder] B o--o r1([red-1.txt ]) B o--o r2([red-2.txt ]) B o--o r3([red-3.txt ]) C o--o P1[pink-sub-folder] C o--o p2(["pink-file.md <br>"]) C o--o p3{{"say_hi.sh <br>"}} P1 o--o p4(["**helloworld.py** <br>"]) P1 o--o p5(["pink-data.csv <br>"]) D o--o b1(["**blue.r** <br>"]) style P1 fill:#f9f,stroke:#333,stroke-width:10px,color:#333 style p2 fill:#ff0,stroke:#333,stroke-width:10px,color:#333
We can use the command cat
with a path to a file to read out the contents: try cat ../pink-file.md
We’ve covered an awful lot of commands now!
mkdir
(make directory), and the name of the new directory as an argument:
mkdir new-dir-name
touch
, and the name of the new file as an argument:touch new-file-name.txt
like_this
or-this
!-this
); Linux will think this is a flag/option to a command..txt
, .md
, .py
etc.If you’re working with old files/directories that have spaces in their names, you’ll need to wrap the path in single quotation marks, 'like this.txt'
Choose some sensible Linux file and folder names!
~
)
mkdir path-to-new-folder
touch path-to-new-file
-p
option:_@username → ~ $ mkdir -p new1/new2/new3 ↵
_@username → ~ $ mkdir new1 new2 new3 ↵
Oftentimes, when you’re doing research on a platform like Aire, you don’t need to do extensive manual editing of files; for example, if you are running multiple R scripts, you would write and test these on your desktop computer and then transfer them over to Aire.
nano
command followed by the name of a file (this can be a new or existing file; Nano will create a file for you if it doesn’t exist)_@username → ~ $ nano new-file.txt ↵
This will open up a new screen in your terminal…
_ GNU nano 7.2 new-file.txt
▮
_
_
_
_
New File
^G Help ^O Write Out ^X Exit
The cursor is shown by the rectangle symbol ▮
_ GNU nano 7.2 new-file.txt
You can type in this file;
you don’t need to click on it.▮
_
_
_
New File
^G Help ^O Write Out ^X Exit
You can start typing.
_ GNU nano 7.2 new-file.txt
To save your edits,
hit ^O to write out.
This means CTRL and o▮
_
_
New File
^G Help ^O Write Out ^X Exit
_ GNU nano 7.2 new-file.txt
To save your edits,
hit ^O to write out.
This means CTRL and o▮
_
Hit ENTER to accept the filename
File Name to write: new-file.txt
^G Help ^C Cancel
_ GNU nano 7.2 new-file.txt
To save your edits,
hit ^X to exit.
This means CTRL and x▮
_
_
Wrote 3 lines
^G Help ^O Write Out ^X Exit
This will close the Nano text editor and return you to the command line.
How comfortable are you using Nano?
mv
The mv
(move) command allows us to move a file or folder to a specified location:
file-name
to the directory new-location
: mv file-name new-location
dir-name
to the directory new-location
: mv dir-name new-location
If you move the file or directory to the same location it’s already in, it renames it.
mv
_@username → ~/somewhere $ cd ↵
_@username → ~ $ touch test-file.txt ↵
_@username → ~ $ ls -F ↵
_blue-folder/ pink-folder/ red-folder/ test-file.txt
_@username → ~ $ mv test-file.txt test-file.md ↵
_@username → ~ $ ls -F ↵
_blue-folder/ pink-folder/ red-folder/ test-file.md
_@username → ~ $ mv test-file.md blue-folder ↵
What’s the result of ls
and ls blue-folder
now? Repeat this with a new directory in your home directory.
mv
mv
works recursively and moves directories (and everything in them).After this course, experiment with moving directories around the virtual machine.
BUT, it’s important to note that you can accidentally overwrite files using mv
: this is why it’s useful to practise and get used to using this command in a safe place!
cp
The cp
or copy command allows us to copy files or directories to specified locations.
_@username → ~/somewhere $ cd ↵
_@username → ~ $ touch new-test.txt ↵
_ You can us ls or ls -F to check the file is created
_@username → ~ $ nano new-test.txt ↵
_ Add some text to the file. After saving, check the content with cat:
_@username → ~ $ cat new-test.txt ↵
_@username → ~ $ cp new-test.txt new-test-2.txt ↵
_ Check the content of new-test-2.txt with cat
cp
The cp
or copy command allows us to copy files or directories to specified locations.
_@username → ~ $ mkdir -p test-dir/sub-dir/sub-sub-dir other-test-dir ↵
_ Explore your new dirs with cd and ls, then return to ~
_@username → ~ $ cp test-dir/sub-dir/sub-sub-dir other-test-dir ↵
_ cp: -r not specified; omitting directory ‘test-dir/sub-dir/sub-sub-dir’
_ We need to add a -r to our command, which means “recursive”
_@username → ~ $ cp -r test-dir/sub-dir/sub-sub-dir other-test-dir ↵
How comfortable are you with exploring and handling directories using the commands we have covered?
rm
Almost everyone who’s used Linux before will have a horror story about the command rm
(remove), and accidentally deleting files they didn’t mean to.
But being able to delete and clean up files is very important, especially when using a shared resource (like Aire) that has storage quotas.
Let’s clean up all the test files we just made.
_@username → ~ $ ls ↵ Check what files you want to delete
_@username → ~ $ rm new-test.txt new-test-2.txt ↵
rm
Deleting directories
_@username → ~ $ rm test-dir ↵ Delete a directory
_ rm: cannot remove ‘test-dir/’: Is a directory
Like cp, we need to tell rm we want it to act recursively, with -r
_@username → ~ $ rm -r test-dir ↵ Delete a directory
This is very powerful and can quickly delete directories of important data!
rm
does not send things to the recycling bin or equivalent: it hard-deletes them; data is usually not recoverable.
rm
A cautionary exercise
Look at the following command and try to predict what it does:
Do not run the following snippet!
rm -rf *
rm
: the delete command (remove)-r
: recursive, so will eat through directories-f
: force - do not ask for clarification, just delete*
: a “wildcard” character; instead of providing a file or directory name, this essentially means everythingBefore we go on a break, cd
back to your home directory, and experience the abject horror of rm
.
Run rm -rf *
from /home/vscode
. Only do this in your virtual machine on codespaces, never on a research machine
Use cd
and ls
to look around - what does your home directory look like now?
>< Codespaces
button in the lower left of your screen, then select “Rebuild Container” from the menu that pops up.ls -F
to list out the contents of ~/pink-folder
say_hi.sh
?This is an executable file - like a Windows .exe
file - you can run it.
Let’s read it first and predict what it will do:
cat say_hi.sh
to print out the contentsWhat’s in say_hi.sh
?
#!/bin/sh
echo "hello!"
echo "Running this file prints out a number of greetings"
echo "What's your name? (type your name in below)"
read yourname
echo "Nice to meet you, $yourname!"
#!/bin/bash
: this is known as “shebang bin bash” tells Linux to use Bash to parse the file - we don’t need to worry about this, beyond knowing to include it at the beginning of a shell script.echo
will just print out (or echo back) any arguments after it.
echo Hello
in your terminalread
command waits for you to type input and press enter, then saves it to a variable
read greeting
and pressing enterHello
, and press enterecho $greeting
and press enter$
What’s in say_hi.sh
?
#!/bin/sh
echo "hello!"
echo "Running this file prints out a number of greetings"
echo "What's your name? (type your name in below)"
read yourname
echo "Nice to meet you, $yourname!"
What do we predict it’s going to do?
_@username → ~/pink-folder $ ./say_hi.sh ↵
Run using ./ in front of the script name
Let’s create a simple bash script. cd
to home and open a new file with Nano:
_@username → ~/pink-folder $ cd ↵
_@username → ~ $ nano test-script.sh ↵
#!/bin/bash
touch test-file-auto.txt
mkdir new-dir-auto
cp test-file-auto.txt new-dir-auto
echo "Put this text in the job report" > job-report.txt
Save the file with Nano.
ls -F
ls -l
It’s just a regular file: we need to make it executable!
_@username → ~ $ chmod +x test-script.sh ↵
The chmod
command changes or modifies file permissions: you need permission to be able to execute a bash script.
+x
add executable permissionstest-script.sh
is the name of the script you want to apply permissions to.Now, try ls -F
again!
_@username → ~ $ ./test-script.sh ↵
What did it do?
echo "Put this text in the job report" > job-report.txt
do?
>
operator directs the output from echo "your message"
to the file job-report.txt
mkdir new-dir-auto
with mkdir -p new-dir-auto
and rerun, what happens?
-p
option (in addition to allowing you to create nested files) also allows you to try to make a folder, and if it already exists, doesn’t failecho "Put this text in the job report" > job-report.txt
to echo "Put this text in the job report" >> job-report.txt
, what does this do?
echo "message" > job-report.txt
or echo "message" >> job-report.txt
and seeing how they behave.In general, on the HPC system, you will want to run scripts in other languages, like R
or Python
(amongst many, many others).
cd
home, and then into the directory blue-folder
:
_@username → ~/wherever $ cd ↵
_@username → ~ $ cd blue-folder ↵
_@username → ~/blue-folder $ ls ↵
_blue.R
This is an R script; if R is installed on the system it can be run with the command Rscript. Check what is in the file before running it with the command cat.
_@username → ~/blue-folder $ cat blue.R ↵
_print(“Hello World”) Ok, lets run it
_@username → ~/blue-folder $ Rscript blue.R ↵
What if we wanted the results saved to a text file?
What if we wanted to run multiple R scripts?
Let’s create a bash script called r-bash.sh
and save it alongside blue.R
; remember you’ll need to do chmod +x r-bash.sh
.
Run this: ./r-bash.sh
; what happens?
We can do the exact same with Python scripts; we only need slightly different commands to run the .py
script.
cd
home, and then into the directory pink-folder/pink-sub-folder
:
_@username → ~/wherever $ cd ↵
_@username → ~ $ cd pink-folder/pink-sub-folder ↵
_@username → ~/pink-folder/pink-subfolder $ ls ↵
_helloworld.py pink-data.csv
Check what is in the Python file before running it with the command cat.
_@username → ~/pink-folder/pink-subfolder $ cat helloworld.py ↵
_print(“Hello World”) Ok, lets run it
_@username → ~/pink-folder/pink-subfolder $ python helloworld.py ↵
Write a bash script that runs the Python script helloworld.py
and saves the output to a text file.
#!/bin/bash
chmod +x name-of-script.sh
chmod +x script-name.sh
to make a bash file executable.>
to write files._@username → ~/wherever $ cd ↵ Or to wherever you want to download the files
_@username → ~ $ wget https://swcarpentry.github.io/shell-novice/data/shell-lesson-data.zip ↵ Download the zip file (expect lots of output)
_@username → ~ $ unzip shell-lesson-data.zip ↵ Unzip the folder (expect lots of output)
wget
is a really useful command for downloading data from the internet. It can take a range of different options and arguments:
wget url-to-data
: this downloads the data to the current working directory, with the folder/file name provided by the URL .wget -O new-nap.zip url-to-data
.wget -P path/to/folder url-to-data
.unzip
is necessary if you are downloading compressed/zipped archives (that end in .zip
)
unzip filename.zip
; this will unzip the file in the current working directory, into a folder called filename
.unzip -l filename.zip
will list the contents of the archive without extracting them.Use the back button in your browser to return to the slide you were previously on.
flowchart TD START:::hidden --> |cd|A A[/home/vscode/] -->|cd red-folder| B[red-folder/ ] A[/home/vscode/] -->|cd pink-folder| C[pink-folder/ ] A[/home/vscode/] -->|cd blue-folder| D[blue-folder/ ] B --- r1([red-1.txt ]) B --- r2([red-2.txt ]) B --- r3([red-3.txt ]) C --- |cd pink-sub-folder|P1[pink-sub-folder/ ] C --- p2([pink-file.md ]) C --- |./say_hi.sh|p3{{say_hi.sh }} P1 --- |python helloworld.py|p4([**helloworld.py** ]) P1 --- p5([pink-data.csv ]) D --- |Rscript blue.r|b1([**blue.r** ])
Scroll down to see key:
flowchart TD E[folder] -->|CLI argument|F([file]) E[folder] -->|CLI argument|G{{executable}}
You can use cat filename
to print out the content of a file, or nano filename
to open the nano text editor. You can also use code filename
to open it in vscode on your virtual machine.
On the HPC system, you’ll likely use nano
to edit code if you ever need to.
Use the back button in your browser to return to the slide you were previously on.
If you are lost, you can always cd
home!
Command | Description |
---|---|
cd |
Change directory to home |
cd dir-name |
Change directory to dir-name |
pwd |
Print the current working directory - where am I? |
name --help |
Load the manual for name - on Codespaces |
man name |
Load the manual for name - on Aire/ARC |
ls |
List the contents of a directory |
cat file-name |
Print out the contents of a file called file-name |
mkdir dir-name |
Make a new directory called dir-name |
touch file-name |
Make a new file/update the last-edited date of a file called file-name |
Some more cd
commands:
Command | Description |
---|---|
cd .. |
Go up a level to the parent directory |
cd - |
Go back to the previous directory |
cd ~/dir-name |
Go to dir-name , a directory in the home directory |
Some more ls
commands:
Command | Description |
---|---|
ls -F |
List the contents of a dir, with symbols for content type |
ls -a |
List all contents, including hidden files and directories |
ls -l |
List contents, including permissions, the owner and their “group”, and when the content was edited |
Commands for working with files and directories:
Command | Description |
---|---|
cp |
|
mv |
|
rm |
|
mkdir -p dir-name |
Make a new directory call dir-name if it doesn’t already exist |