{ "cells": [ { "cell_type": "markdown", "id": "5e51bb19", "metadata": {}, "source": [ "# BASH commands\n", "\n", "```{admonition} Interactive page\n", ":class: warning, dropdown\n", "This is an interactive book page. To solve quizzes, press the launch button at the top right side of the page \n", "(look for a small rocket icon) and then *Live Code*. \n", "```\n", "\n", "To begin familiarizing yourself with the terminal, we first provide an overview of commonly used BASH commands ({numref}`bash-commands-table`), which are explained in more detail below on this page. \n", "The overview is not exhaustive - if you want to perform an action not covered by the table, search online to find an appropriate command.\n", "To run a command on your computer, simply open your terminal, type in the command, and press Enter." ] }, { "cell_type": "markdown", "id": "30107bb7", "metadata": {}, "source": [ "```{list-table} Overview of basic BASH commands. Note that commands are often based on their effect, e.g., the *pwd* command **p**rints **w**orking **d**irectory. Commands can be executed (ran) alone or with specific options (**flags**), which allow for nuancing of the performed action.\n", ":class: dropdown\n", ":header-rows: 1\n", ":name: bash-commands-table\n", "\n", "* - Command\n", " - Effect\n", " - Details\n", "* - `pwd`\n", " - Print working directory\n", " - Display the location (**path**) of the directory in which you're currently working.\n", "* - `cd`\n", " - Change directory\n", " - Navigate between directories. To go to the home directory, use `cd` without specifying any directory.\n", "* - `mkdir`\n", " - Make a new directory\n", " - Creates a new empty directory with the user-defined name.\n", "* - `rmdir`\n", " - Remove a directory\n", " - Deletes a directory if it's **empty**. See also `rm`.\n", "* - `ls`\n", " - List contents of a directory\n", " - Use with `-l` or `-lh` for a more detailed overview.\n", "* - `less`\n", " - Open a file to view its contents. To exit an opened file, press `q`. \n", " - Doesn't allow for file editing.\n", "* - `cat`\n", " - Print file contents to terminal \n", " - If used with more than one file, it concatenates them and prints the result in the terminal.\n", "* - `cp`\n", " - Copy\n", " - Copy a file to another directory, or make a file copy in the same location. To copy a directory with all its contents, use `cp -r` (`-r` stands for *recursive*). \n", "* - `mv`\n", " - Move / Rename\n", " - Moves or renames files. Renames directories. To move directories with their contents, use `mv -r`.\n", "* - `rm`\n", " - Remove\n", " - Deletes a file. `rm -r` deletes a directory and all its contents.\n", "* - `grep`\n", " - Search\n", " - Search for text patterns.\n", "* - `clear`\n", " - Clear terminal window\n", " - Clears commands and outputs to declutter the terminal.\n", "* - `.`\n", " - Current folder\n", " - \n", "* - `..`\n", " - One folder up (parent folder)\n", " - \n", "* - `*`\n", " - Wildcard\n", " - Replaces any text.\n", "* - `>`\n", " - Redirect\n", " - Instead of printing output of running a script in the terminal, with `>` the output can be redirected into a file.\n", "```\n", "\n", "```{admonition} Online information\n", ":class: tip, dropdown\n", "Don't hesitate to look for information online (Google, StackOverflow, ChatGPT) when you're not sure how to do something, or what is the exact command that you need to use.\n", "```" ] }, { "cell_type": "markdown", "id": "a9e8963f", "metadata": {}, "source": [ "## Navigating directories\n", "\n", "**Effectively navigating directories with the `cd` command is at the very core of working with the terminal** - we have to know in which directory we are currently working. In addition, knowing our location is essential for several commands, such as `cp` and `mv` discussed below. Let's take a closer look at navigating directories inthe terminal.\n", "\n", "Every directory on your computer has a specific **path** assigned to it.\n", "You can think of the overall arrangement of folders on your computer as a **tree** ({numref}`folder-tree`) and paths as **addresses** within the tree.\n", "The root of the tree is called **root directory**.\n", "Each user also has their own **home directory** - this is the default location when you first open your terminal, and the place you're brought to when you use the command `cd` without specifying to which folder you wish to go.\n", "\n", "```{figure} ../images/chapter2/folder-tree.png\n", "---\n", "height: 300px\n", "name: folder-tree\n", "---\n", "An example of a folder tree. The root directory is colored blue, and the *home* directory for user *Nina* is colored green.\n", "```\n", "\n", "A path to a specific location can be:\n", "- **Absolute**, i.e., with respect to the *root*: using `pwd` command in the terminal will always print the absolute path for your current location, which can look something like `Users/Anna/Documents/Research/`. \n", "- **Relative**, i.e., with respect to your current location. It's useful to know the following notation: \\\n", "`.` = current directory \\\n", "`..` = one directory up in the tree (parent directory) \\\n", "These can then be stacked, e.g., you can move one directory up from your current directory with `cd ../`, two directories up with `cd ../../`, etc.\n", "\n", "```{admonition} Home and root directories\n", ":class: tip\n", "The tilde `~` is a shortcut to denote a home directory. Therefore, you can use the tilde followed by a slash `~/` as the beginning of a path to a file or directory in the home directory. To change directory from any directory directly to the home directory, use `cd` or `cd ~`.\n", "Similarly, to navigate from anywhere directly to the root directory, use `cd /`.\n", "```\n", "\n", "```{admonition} Names of directories and files\n", ":class: tip, dropdown\n", "It is good practice **not to use spaces** in your directory and file names, as it makes working with the terminal easier.\n", "When your file or directory contains several words, **use underscore** `_` for easy recognition of the words while at the same time avoiding spaces.\n", "For instance, use `My_new_file.txt` instead of `My new file.txt`.\n", "```\n", "\n", "In {numref}`folder-tree`, you can imagine the following navigation between directories:\n", "1. When opening the terminal of user *Nina*, we are located in the *home* directory of *Nina*, which is called `Nina/`.\n", "2. `cd Downloads/Movies/` brings us to the directory `Movies/` - now we're moving down or deeper into the tree.\n", "3. To go back to the directory `Nina/`, we can use either `cd ../../` or `cd` (because `Nina/` is the *home* directory).\n", "4. To navigate from `Nina/` to `Systems/`, we use `cd ../../Systems/`, thereby first moving two folders up to *root*, and then going down into the `Systems/` directory.\n", "\n", "Of course, **you don't have to know the directories arrangement on your computer by heart**.\n", "Whenever you're not sure in which directory you're located, use `pwd` to learn its absolute path.\n", "To see which directories (and files) are placed in your current directory, use `ls`, `ls -l`, or `ls -lh`.\n", "Similarly, to see which directories (and files) are located one directory up, you can use `ls ..`, `ls -l ..`, or `ls -lh ..`.\n", "\n", "```{admonition} ls command\n", ":class: note, dropdown\n", "The `ls` command lists the contents of the current directory and can be used with flags `-l` or `-lh`, among others.\n", "The `-l` flag gives more information about files in the directory, while `-lh` (*h* for *h*uman) also shows file sizes in a human-readable way ({numref}`terminal-ls`).\n", "\n", "```{figure} ../images/chapter2/terminal-ls.png\n", "---\n", "height: 400px\n", "name: terminal-ls\n", "---\n", "Listing contents (`fileA.txt` and `fileB.txt`) of *My_folder* in the terminal using `ls`, `ls -l`, and `ls -lh`.\n", "```\n" ] }, { "cell_type": "code", "execution_count": null, "id": "52ecf718", "metadata": { "tags": [ "thebe-remove-input-init" ] }, "outputs": [], "source": [ "import micropip\n", "await micropip.install(\"jupyterquiz\")\n", "from jupyterquiz import display_quiz\n", "import json\n", "\n", "with open(\"question1.json\", \"r\") as file:\n", " questions=json.load(file)\n", " \n", "display_quiz(questions, border_radius=0)" ] }, { "cell_type": "markdown", "id": "8b936efd", "metadata": {}, "source": [ "\n", "\n", "```{exercise} \n", ":class: dropdown\n", "Open the terminal on your laptop. Using the commands explained in the text above, such as `pwd`, `cd`, and `ls`, explore directories on your computer.\n", "```\n", "\n", "```{exercise} \n", ":class: dropdown\n", "Open your terminal. Run the following commands in consequtive order. After running each command, ask yourself: *What is the absolute path of your current directory?*\n", "\n", "1. `pwd` \n", "2. `cd Downloads/` \n", "3. `cd ../`\n", "4. `cd ../`\n", "5. `cd`\n", "\n", "Was it possible to execute these commands? If not, why? In the latter case, you can try again starting the first step from your home directory.\n", "\n", "Using pen and paper, make a diagram of how you were navigating through your directories using these commands.\n", "```\n", "\n", "```{admonition} Tree\n", ":class: note, dropdown\n", "\n", "As you've experienced by now, exploring your directories with `ls` command can be a bit tedious. People have, therefore, devised a specialized terminal command that gives you a more graphical overview of your directories - `tree`. If you try to run `tree` in your terminal and nothing happens, that means that it's currently not installed. In Cygwin, you could use the same procedure as when installing unzip and Vim. For Linux terminal, you could use `sudo apt-get install tree`. For macOS, follows instructions in book section 2.1, after which you can use `brew install tree`.\n", "```" ] }, { "cell_type": "markdown", "id": "b39d47da", "metadata": {}, "source": [ "```{admonition} Autocomplete\n", ":class: tip\n", "If you're working with a **long path, directory, and/or file names**, typing their names can be a daunting and (more importantly) **error-prone** task.\n", "To make this easier and faster, you can use `Tab` for **autocompletion**.\n", "If the name you're aiming for is unique, it will get autocompleted with `Tab`.\n", "Otherwise, you will need to type one or a few more letters to help the autocomplete get to a unique point.\n", "Pressing `Tab` twice will give you a list of options.\n", "```\n", "\n", "```{exercise}\n", ":class: dropdown\n", "Open your terminal. \n", "1. What happens if you type `cd` and then press `Tab`? How about when you press `Tab` once again?\n", "2. How about typing `cd D` or `cd Dow`, followed by `Tab`?\n", "```" ] }, { "cell_type": "markdown", "id": "7dd5f41d", "metadata": {}, "source": [ "## Manipulating directories\n", "\n", "With the terminal you can easily **create** (`mkdir A/`) or **delete** an empty directory `A/` (`rmdir A/`), where `A/` can be something like `Movies/` in the figure above. \n", "You can also use `rm` to delete directories, `cp` to copy, and `mv` to move and rename them.\n", "\n", "If you have a directory with files inside (i.e, a non-empty directory), you cannot use `rmdir` to delete it. In order to delete a non-empty directory with all its contents, you need to use `rm` in a recursive fashion: `rm -r A/`.\n", "\n", "Similarly, if you wish to make a **copy** of a directory (with all its contents), this also has to be done recursively. \n", "Notice the nuanced differences between the following commands:\n", "- `cp -r A/ new_A/` - makes a copy of the source directory `A/` with all its contents; the new folder is called `new_A/`. \n", "- `cp -r A new_A/` - same as previous command.\n", "- `cp -r A/ existing_A/` - copies the **contents** of the source directory `A/` to the existing destination directory `existing_A`.\n", "- `cp -r A existing_A/` - makes a copy of the **directory** `A/` with all its contents inside the existing directory `existing_A`.\n", "Therefore, the presence or absence of the trailing slash `/` in the source directory determines whether the entire directory is copied as a subdirectory or only its contents are copied.\n", "\n", "*Note*: in Cygwin, there is no difference between the latter two commands, but in macOS/Linux terminal there is.\n", "\n", "In addition to copying, we can also move directories.\n", "To **move** directory `A/` with all its contents into directory `B/`, we can use `mv A/ B/` (note: `mv` doesn't differentiate based on the presence or absence of a trailing slash in the source directory).\n", "We can also use `mv` to **rename** a directory like this: `mv A/ new_name_A/`.\n", "\n", "```{exercise}\n", ":class: dropdown\n", "Try to use `rm` with one of your non-empty folders. What message does the terminal return?\n", "```\n", "\n", "```{exercise}\n", ":class: dropdown\n", "In your terminal:\n", "1. Navigate to your desired working directory (this could be, e.g., `Documents/` or `Desktop/`).\n", "2. Create two new directories: name them `A` and `existing_A`.\n", "3. Copy any file to directory `A/`. Because we don't yet know how to do it in the terminal, you can do it using your mouse and GUI.\n", "4. From your working directory, try to run the `cp` and `mv` commands mentioned above and observe what the effects are. Note: you may need to \"reset\" your setup with two folders depending on which command you ran.\n", "```\n", "\n", "```{admonition} Recalling previous commands \n", ":class: tip\n", "Sometimes you want to use the same command you used recently in your terminal, either to run it again, or make a small modification and then run it.\n", "There's an easy way to fetch your previously executed commands **instead of retyping** them: you can simply press arrow up (↑) once or multiple times. \n", "To print a full list of recent commands, use `history` command.\n", "\n", "Try it in your terminal!\n", "```\n" ] }, { "cell_type": "markdown", "id": "bd356573", "metadata": {}, "source": [ "## Working with files\n", "\n", "Several commands that apply to working with directories also apply to files.\n", "Let's take a look at what the following commands mean:\n", "- `cp a.txt b.txt` - copies `a.txt` to `b.txt` in the same directory. Using `mv` instead of `cp` would rename `a.txt` into `b.txt`.\n", "- `cp a.txt ../` - copies `a.txt` to one directory up (it can also be used with `mv` to move the file).\n", "- `cp a.txt A/` - as previous command, but copies `a.txt` in the directory `A/` (can also be used with `mv`).\n", "- `cp ../a.txt .` - copies `a.txt` from one directory up to the current (`.`) directory (it can also be used with `mv`).\n", "\n", "\n", "\n", "### Wildcard \n", "\n", "Sometimes you will want to copy or move multiple files or directories at the same time.\n", "To avoid typing each command individually or recalling the same command and changing it multiple times, you can use the wildcard `*` to **replace any text**.\n", "\n", "For instance, let's say we are located in the directory `Physics`:\n", "\n", "\n", "```{figure} ../images/chapter2/wildcard.png\n", "---\n", "height: 250px\n", "name: wildcard-tree\n", "---\n", "Example folder: wildcard usage.\n", "```\n", "\n", "If we are in the directory `Physics` and want to move all Notes files into directory `Materials/`, we could use `mv Notes* Materials/`.\n", "With `Notes*`, we included all three `.docx` files. Therefore, `*` effectively means `Nov21.docx` **or** `Nov24.docx` **or** `Oct16.docx`.\n", "\n", "We could alternatively use `mv N* Materials/` because our three files with notes are the only files beginning with letter *N*, so `mv N*` already defines our selection. Another option would be to use `mv *docx Materials/` because Notes are the only `.docx` files in the directory `Physics/`.\n", "\n", "Note that it's also possible to use multiple wildcards in one go if there are several patterns you wish to generalize. E.g., to delete all `.docx` files that have *Nov* in their name, you can use `rm *Nov*.docx`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "b9cc7370", "metadata": { "tags": [ "thebe-remove-input-init" ] }, "outputs": [], "source": [ "import micropip\n", "await micropip.install(\"jupyterquiz\")\n", "from jupyterquiz import display_quiz\n", "import json\n", "\n", "with open(\"question2.json\", \"r\") as file:\n", " questions=json.load(file)\n", " \n", "display_quiz(questions, border_radius=0)" ] }, { "cell_type": "markdown", "id": "24da913a", "metadata": {}, "source": [ "### Reading files\n", "For taking a glance at the contents of a text file in read-only mode, `less` comes in very handy.\n", "To open a file for reading, we use `less file.txt`.\n", "We can further navigate through the text of a file by scrolling or search for specific text patterns like this: `/Pattern` (note that this is case sensitive, i.e., there is a difference between `/Pattern` and `/pattern`).\n", "To navigate to the end of the file, use `G`. To move to the beginning of the file, use `g`.\n", "To close the file, simply press `q` (for \"quit\") on your keyboard.\n", "\n", "An alternative command used to read the contents of a file is `cat`. \n", "Unlike the `less` command which opens a file, `cat` prints a file's contents to your terminal.\n", "If you use it with more than one file, e.g., `cat fileA.txt fileB.txt`, it will concatenate the files and print the output in the terminal." ] }, { "cell_type": "markdown", "id": "772e27c8", "metadata": {}, "source": [ "### Editing files with Vim \n", "Vim is a powerful **text editor** which you can use from within the terminal.\n", "Unlike text editors such as Notepad or MS Word, Vim is entirely command-based.\n", "That means that even simply writing some new text in the file requires extra steps instead of just starting to type (concretely, you have to press `i` to let Vim know that you wish to type new text).\n", "Upside: you *can't accidentally add* new text, which is actually quite useful when working with coding and scripts.\n", "Vim does take some getting used to, but is ultimately a powerful text editor and usually comes pre-installed (e.g., when you remotely connect to a supercomputing cluster such as DelftBlue)." ] }, { "cell_type": "markdown", "id": "72701690", "metadata": {}, "source": [ "#### Opening and closing files\n", "\n", "To open a file in Vim, use: \n", "```\n", "vim filename.txt\n", "```\n", "\n", "If filename.txt **exists**, it will open for editing. If it **does not exist**, a new file with that name will be created.\n", "\n", "There are several options to exit Vim:\n", "- :q → quit (only works if no changes were made)\n", "- :q! → quit without saving\n", "- :wq → save and quit" ] }, { "cell_type": "markdown", "id": "cb50c273", "metadata": {}, "source": [ "```{exercise}\n", ":class: dropdown\n", "Try out the commands for opening and closing files in Vim in your terminal. You can use a new or an existing file.\n", "```" ] }, { "cell_type": "markdown", "id": "e502cd7c", "metadata": {}, "source": [ "#### Vim's modes\n", "\n", "Unlike standard text editors, Vim operates in different **modes**:\n", "- Normal mode (default) – used for navigation, copying, pasting, deleting, and running commands.\n", "- Insert mode (activated with `i`) – used for typing text.\n", "- Visual mode (activated with `v` or `V`) – used for selecting text. See more [here](https://opensource.com/article/19/2/getting-started-vim-visual-mode).\n", "- Command mode (activated with `:`) – used for saving, quitting, and running advanced commands.\n", "\n", "You can also **switch between modes** when you work on a file. To do so:\n", "- Press `i` to enter insert mode\n", "- Press `Esc` to return to normal mode\n", "- Use `:` to enter command mode" ] }, { "cell_type": "markdown", "id": "1692264b", "metadata": {}, "source": [ "\n", "\n", "```{list-table} Basic Vim commands. More commands can be found [online](https://vim.rtorr.com/).\n", ":header-rows: 1\n", ":name: vim-commands-table\n", "\n", "* - Command\n", " - Effect\n", " - Details\n", "* - `i`\n", " - Insert text\n", " - Puts Vim in insert mode, allowing text entry.\n", "* - `Esc`\n", " - Exit insert mode\n", " - Return to normal mode.\n", "* - `u`\n", " - Undo\n", " - Reverts the last change.\n", "* - `Ctrl` + `r`\n", " - Redo\n", " - Re-applies an undone change.\n", "* - `dd`\n", " - Delete line\n", " - Removoes the current line. Use `5dd` to delete 5 lines. Use `dG` to delete everything from the current line (cursor position) to the end of the file.\n", "* - `x`\n", " - Delete a character\n", " - Deletes a character at the position of the cursor.\n", "* - `yy`, `p`\n", " - Copy-paste\n", " - `yy` copies the current line, while `p` pastes copied content below the cursor. To paste above, use `P`. \n", "* - `:%s/old/new/gc`\n", " - Replace\n", " - Replaces occurrences of `old` with `new`. `c` allows you to decide manually for each `old` whether it should be changed to `new` or not. Using only `g` replaces all occurences of `old` with `new` without asking further user's input. \n", "* - `/pattern`\n", " - Search for text\n", " - Finds the next occurrence of `pattern`. Use `n` to jump to the next match, or `N` to go the previous one.\n", "* - `gg` and `0`\n", " - Beginning\n", " - `gg` brings the cursor to the beginning of the file, `0` to the beginning of the line.\n", "* - `G` and `$`\n", " - End\n", " - `G` brings the cursor to the end of the file, `$` to the end of the line.\n", "* - `h`, `j`, `k`,`l`\n", " - Move cursor \n", " - Left, down, up, and right, respectively.\n", "* - `:set nu`\n", " - Show line numbers\n", " - Displays line numbers on the left.\n", "* - `v`\n", " - Enter visual mode\n", " - Enables text selection for copy/paste.\n", "* - `V`\n", " - Visual Line Mode\n", " - Selects whole lines instead of individual characters.\n", "* - `q`\n", " - Macro\n", " - Allows for defining custom macros (think of those as functions).\n", "* - `:w`\n", " - Save file\n", " - Saves changes without quitting.\n", "* - `:q`\n", " - Close file\n", " - `q` exits Vim (only if no changes are made).`:q!` closes file without saving the made changes. It can be used together with `w` as `:wq`, which saves all changes and closes the file in one go. \n", "```\n" ] }, { "cell_type": "markdown", "id": "5886eebe", "metadata": {}, "source": [ "```{exercise}\n", ":class: dropdown\n", "Open a terminal and navigate to your desired directory. Create and open a new file with `vim my_file.txt`. Press `i` to enter insert mode. Type a few lines of text, making sure they contain the following words: \"word\" and \"foo\". Press `Esc` to exit insert mode. Save the file and exit using `:wq`. Reopen the file in Vim or with `less` to confirm your changes.\n", "```" ] }, { "cell_type": "markdown", "id": "5bcecc07", "metadata": {}, "source": [ "```{exercise}\n", ":class: dropdown\n", "Open `my_file.txt` from the previous exercise in Vim. Use these commands to experiment:\n", "- `yy` to copy a line, `p` to paste it.\n", "- `dd` to delete a line.\n", "- `/word` to search for \"word\" in the file.\n", "- `:%s/foo/bar/gc` to replace \"foo\" with \"bar\".\n", "When you're done, save and exit.\n", "```" ] }, { "cell_type": "markdown", "id": "046e96a9", "metadata": {}, "source": [ "```{admonition} Advanced example: using macros\n", ":class: note, dropdown\n", "\n", "Vim allows for automating repetitive tasks using macros. \n", "\n", "Let's consider the following task: **Replace every occurrence of \"A\" with \"B\" in 1,000 consecutive lines.**\n", "To do this in Vim, we can build a macro using these steps:\n", "1. Position your cursor on the first \"A\".\n", "2. Start recording a macro with `qa` → `q` starts recording, and `a` is the macro name.\n", "3. Type `i B Esc j` → `i` enters insert mode, `B` replaces \"A\" with \"B\", `Esc` exits insert mode, `j` moves cursor down one line.\n", "4. Stop recording with `q`.\n", "5. Run the macro 1000 times with `1000@a`.\n", "\n", "This automates the task efficiently!\n", "```" ] }, { "cell_type": "code", "execution_count": null, "id": "216b2430", "metadata": { "tags": [ "thebe-remove-input-init" ] }, "outputs": [], "source": [ "import micropip\n", "await micropip.install(\"jupyterquiz\")\n", "from jupyterquiz import display_quiz\n", "import json\n", "\n", "with open(\"question3.json\", \"r\") as file:\n", " questions=json.load(file)\n", " \n", "display_quiz(questions, border_radius=0)" ] } ], "metadata": { "jupytext": { "formats": "ipynb,md" }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }