#+title: lesson 02 | course overview + the shell
#+HTML_HEAD:
#+HTML_HEAD:
#+HTML_HEAD:
#+OPTIONS: H:6
* Links
#+attr_html: :class links
- [[../toc.org][TOC | Missing Semester]]
- [[https://www.youtube.com/playlist?list=PLyzOVJj3bHQuloKGG59rS43e29ro7I57J][Playlist: Missing Semester]]
- Curr: https://youtu.be/kgII-YWo3Zw?si=Wm8KLT1ggOGG8W-g&t=1692
*** timestamps
:PROPERTIES:
:CUSTOM_ID: timestamp
:END:
#+attr_html: :class playlist
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=54s][00:54 - control flow functions]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=227s][03:47 - sequential execution]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=425s][07:05 - standard input]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=444s][07:24 - error code]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=517s][08:37 - logical operators]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=603s][10:03 - concatenate commands]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=645s][10:45 - common substitution]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=675s][11:15 - process substitution]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=935s][15:35 - comparison operator]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=1173s][19:33 - curly braces]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=1359s][22:39 - python script]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=1707s][28:27 - man command]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=2175s][31:26 - finding files]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=2190s][36:30 - grep]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=2573s][42:53 - fuzzy finder]]
+ [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=2649s][44:09 - history substring search]] *current*
* Notes
** bash
*** spaces are critical with bash
- this works:
#+begin_src bash
foo=bar
echo $foo
#+end_src
- this doesn't:
#+begin_src bash
foo = bar
echo $foo
#+end_src
- the output of that will be
=zsh: command not found: foo=
- what happens in the above example is that we are effectively calling the "foo" program with the arguments: "=" and "bar"
*** quotes
- you can use double or single quotes to print a value
#+begin_src bash
echo "Hello"
#+end_src
#+begin_src bash
echo 'Hello'
#+end_src
- double quotes can interpolate variables
#+begin_src bash
echo "Value is $foo"
#+end_src
will return: =Value is bar=
- single quotes can NOT interpoloate variables
#+begin_src bash
echo 'Value is $foo'
#+end_src
will return: =Value is $foo=
** sequential execution
*** bash functions
- mcd.sh
#+begin_src bash
mcd() {
mkdir -p "$1"
cd "$1"
}
#+end_src bash
- creates a function that can be executed after loading
- $1 is a global variable referring to the first parameter
*** source
- using source mcd.sh
=source mcd.sh=
- then carry out the function
=mcd testdir=
- this will create a new directory and cd into it as per the definied functioned
** error codes
*** commands to access codes or values
- $0 -- name of the script we are currently in
- if you run this in the shell it will display 'bash'
- $1->$9 -- the first through ninth argument given to a script
- $? -- the last error message
- $_ --- last argument of the previous call
- !! -- recreates the last call with it's arguments
- use with sudo if you found your call needed a sudo and you don't feel like retyping it again
#+begin_src bash
ls -lah
sudo !!
#+end_src
*** code values
- boolean
- true returns an error code of 0
- false returns an error code of 1
** using $@ and $*
- represents all the arguments passed to a script or a function as separate, individual strings. It preserves each argument as a distinct item, even if the argument contains spaces.
*** key points about $@
1. All Arguments: It refers to all the command-line arguments passed to the script.
2. Preserves Spaces: If an argument contains spaces, it is treated as a single argument.
3. Usage: It is commonly used in a loop to iterate over each argument.
*** example
#+begin_src bash
./myscript.sh file1.txt "file with spaces.txt" file3.txt
#+end_src
then $@ will be
=file1.txt "file with spaces.txt" file3.txt=
*** differences between $*
- *$@* treats each argument as a sepearte item
- *$** treats all arguments as a single, combined string
** logical operators
- you can use the error return value in conditionals
*** example using the OR conditional
#+begin_src bash
false || echo "Oops fail"
"Oops fail"
#+end_src
*** example using the AND conditional
#+begin_src bash
true && echo "this will print"
"this will print"
#+end_src
** concatenate commands
- you caoncatinate commands using the semicolon: *;*
#+begin_src bash
false; echo "this prints always"
"this prints always"
#+end_src
** common substitution
- take the output of a command and put it in a variable
#+begin_src bash
foo=$(pwd)
echo $foo
"/Users/ronny/..."
#+end_src
- this can also be done by placing that format in a string and it will expand the string
#+begin_src bash
echo "the pwd output is: $(pwd)"
"the pwd output is: /Users/ronny/..."
#+end_src
** process substitution
*** description
Bash process substitution is a feature that allows you to use the output of a command or a process as if it were a file. It enables you to redirect input or output between processes in a flexible way without needing intermediate temporary files.
*** Syntax
- creates a temporary file descriptor for the output of the command, which can be used as an input file in another command.
#+begin_src bash
<(command)
#+end_src
- creates a temporary file descriptor for writing to the command, which can be used as an output file in another command.
#+begin_src bash
>(command)
#+end_src
*** examples
- this will take b, a, d, c and sort it so the result is 'a, b, c, d'
#+begin_src bash
sort <(echo -e "b\na") <(echo -e "d\nc")
#+end_src
- this will list the files, send the list to *tee* which will split a portion off to the screen and the rest to grep, followed by text_files.txt
#+begin_src bash
ls | tee >(grep "txt" > text_files.txt)
#+end_src
#+begin_src bash
echo "Starting program at $(date)" # Date will be substituted
echo "Running program $0 with $# arguments with pid $$"
for file in "$@"; do
grep foobar "$file" > /dev/null 2> /dev/null
# when pattern is not found, grep has exit status 1
# we redirect STDOUT and STDERR to a null register since we do not care about them
if [[ "$?" - ne 0 ]]; then
echo "File $file does not have any foober adding one"
echo "# foobar" >> "$file"
fi
done
#+end_src
- *$$* pid given for program
- *$#* number of arguments
- *$@* expands to all the arguments
- can be used in a for loop
- *2>* refers to STDERR
- *>* refers to STDOUT
** test utility
test is a bash utility that you can use to test the condition of a file. look at the man page for more info
** curly braces
curly braces are used as a form of program command expansion.
the braces contain a number of arguments seperated by commans that will expand into arguments for the program
*** example
#+begin_src bash
touch foo{,1,2,10}
touch foo foo1 foo2 foo10
cp foo{,.old}
cp foo foo.old
#+end_src
*** ranges
this takes the format {1..20}
#+begin_src bash
touch directory{1..4}/foo{a..z}.txt
#+end_src
** python scripts
*** making them bash executable
- reference the python compiler at the top of the file
- do it directly:
#+begin_src bash
#!/usr/local/bin/python
#+end_src
- use the env program to do so
#+begin_src bash
#!/usr/bin/env python
#+end_src
*** args can be found through sys.argv[1:]
#+begin_src python
import sys
for arg in reversed(sys.argv[1:]):
print(arg)
#+end_src
** checking for problems in bash scripts using 'shellcheck'
#+begin_src bash
shellcheck some_bash_script.sh
#+end_src
- will tell you problems
- and warnings
** man command
- works with both os, and installed tools
- 'tldr' is easier to read
** find
*** grep
- grep TEXT-TO-FIND LOCATION
- this will recursively go through all files in a directory looking for "TEXT"
#+begin_src bash
grep -R TEXT .
#+end_src
*** ripgrep
**** Key Features of rg (ripgrep):
- Faster than grep (built with Rust and optimized for performance).
- Ignores files listed in .gitignore by default.
- Supports recursive searches automatically.
- Better default output formatting.
- Supports regex matching like grep -E.
- Multithreaded searching for better performance on modern CPUs.
**** basic command structure
- search recursively through all files for text
#+begin_src bash
rg "text"
#+end_src
- case insensitive search
#+begin_src bash
rg -i "text"
#+end_src
- show line numbers
#+begin_src bash
rg -n "text"
#+end_src
- search files of the pattern shown
#+begin_src bash
rg "text" --glob "*.txt"
#+end_src
- search through files that are classified under the type given
- pattern example
#+begin_src bash
rg "text" -t txt
#+end_src
- for example type 'txt' would search for
- txt
- md
- rst
- if you want to see the type list use
#+begin_src bash
rg --type-list
#+end_src
- ask for a specified number of lines of context around search match
#+begin_src bash
rg "text" -C 3
#+end_src
- dont ignore hidden files
#+begin_src bash
rg "text" -u
#+end_src
- add stats to search
#+begin_src bash
rg "text" --stats
#+end_src
*** other alternatives
- ack
- ag
** fuzzy finder
*** Overview of fzf
fzf is a fuzzy finder for the command line. It allows quick searching through lists (files, command history, processes, etc.) using an interactive interface. Unlike traditional search tools that require exact matches, fzf uses fuzzy matching, meaning you only need to type parts of what you're looking for, and it will find the closest match.
*** Why Use fzf?
- Fast and efficient, even for thousands of files or lines.
- Highly customizable, works with various CLI tools (find, grep, git, history, etc.).
- Interactive, allowing navigation with arrow keys or Ctrl-N / Ctrl-P.
- Minimal setup required, just install and start using it.
*** Test Commands to Try in fzf
**** Basic Usage
1. **Search files in the current directory**
#+begin_src sh
fzf
#+end_src
Opens an interactive search where you can start typing to filter through files.
2. **Search your command history**
#+begin_src sh
history | fzf
#+end_src
Lets you browse and select previously used commands.
3. **Find and open a file in Vim**
#+begin_src sh
vim $(fzf)
#+end_src
Searches for a file and opens it in Vim.
4. **Search running processes**
#+begin_src sh
ps aux | fzf
#+end_src
Lets you search for running processes.
5. **Find a Git-tracked file**
#+begin_src sh
git ls-files | fzf
#+end_src
Searches only files tracked by Git.
**** Advanced Usage
6. **Find and delete a file**
#+begin_src sh
rm -i $(fzf)
#+end_src
Select a file to delete (prompts before deletion).
7. **Search and kill a process**
#+begin_src sh
kill -9 $(ps aux | fzf | awk '{print $2}')
#+end_src
Finds a process and terminates it.
8. **Use fzf with ripgrep (fast file search)**
#+begin_src sh
rg --files | fzf
#+end_src
Searches only through files tracked by ripgrep.
9. **Preview file contents while searching**
#+begin_src sh
fzf --preview "bat --style=numbers --color=always {}"
#+end_src
Uses bat (a better cat) to preview file contents.
*** Customizing fzf
**** Set up a keybinding (Ctrl+T) to trigger fzf for file selection
#+begin_src sh
bind '"\C-t": "fzf\n"'
#+end_src
**** Change fzf options to improve display
#+begin_src sh
export FZF_DEFAULT_OPTS="--height 40% --layout=reverse --border"
#+end_src
- --height 40%: Shows results in a smaller window.
- --layout=reverse: Shows matches from the bottom up.
- --border: Adds a visible border.
*** Final Thoughts
- fzf is a powerful tool for navigating files, commands, and processes.
- Once installed, just type fzf anywhere in the terminal and start filtering.
- Combine it with other commands for maximum efficiency.
** tree
*** Overview of tree
tree is a command-line utility that displays directory structures in a tree-like format. It recursively lists files and directories, making it useful for visualizing folder hierarchies.
*** Why Use tree?
- Provides a clear hierarchical view of files and directories.
- Supports filtering by file type, depth, and patterns.
- Can output results in various formats such as JSON and XML.
- Useful for quickly understanding directory structures.
*** Test Commands to Try in tree
**** Basic Usage
1. **Display the directory structure from the current location**
#+begin_src sh
tree
#+end_src
Lists all files and folders in a tree format.
2. **Limit the depth of displayed directories**
#+begin_src sh
tree -L 2
#+end_src
Shows only two levels of the directory structure.
3. **Show hidden files in the tree**
#+begin_src sh
tree -a
#+end_src
Displays all files, including hidden ones (those starting with a dot).
4. **Display file sizes and permissions**
#+begin_src sh
tree -h -p
#+end_src
Shows human-readable file sizes along with permission flags.
5. **List only directories**
#+begin_src sh
tree -d
#+end_src
Displays only directories, excluding files.
**** Advanced Usage
6. **Output the tree structure to a file**
#+begin_src sh
tree > structure.txt
#+end_src
Saves the tree output to a text file for later reference.
7. **Generate JSON output**
#+begin_src sh
tree -J
#+end_src
Outputs the directory structure in JSON format.
8. **Filter by file extension**
#+begin_src sh
tree -P "*.txt"
#+end_src
Lists only `.txt` files within the directory structure.
9. **Exclude certain files or directories**
#+begin_src sh
tree -I "node_modules"
#+end_src
Hides the `node_​modules` directory from the output.
*** Customizing tree
**** Set an alias for a commonly used tree command
#+begin_src sh
alias t2="tree -L 2"
#+end_src
Creates an alias `t2` to quickly show two levels of the directory.
**** Change default colors in tree output
#+begin_src sh
export TREE_COLORS="di=1;34:ln=1;36:fi=0;37"
#+end_src
Customizes the colors used in the tree display for directories, links, and files.
*** Final Thoughts
- tree is a powerful tool for quickly understanding directory structures.
- It is useful for documentation, debugging, and navigating complex file systems.
- The command supports various output formats, filtering, and customization options.
** broot
*** Overview of broot
broot is a command-line tool for navigating and managing directory structures efficiently. It provides a tree-like view of files and directories while allowing fuzzy searching, filtering, and file operations within the terminal.
*** Why Use broot?
- Provides an interactive tree view of directories with better readability than `ls` or `tree`.
- Allows fuzzy searching and filtering of files and directories.
- Supports file operations (e.g., rename, delete, move) directly from the interface.
- Can replace `cd` by letting you navigate and enter directories quickly.
- Supports customizable keybindings and themes.
*** Test Commands to Try in broot
**** Basic Usage
1. **Launch broot**
#+begin_src sh
broot
#+end_src
Opens an interactive directory tree view.
2. **Navigate the file system with fuzzy search**
#+begin_src sh
broot
#+end_src
Start typing part of a file or directory name to filter results.
3. **Enter a directory from broot**
#+begin_src sh
br
#+end_src
If `br` is set up as a shell function, it allows `cd` replacement.
4. **Show hidden files**
#+begin_src sh
broot --hidden
#+end_src
Displays hidden files and directories.
5. **Only show directories**
#+begin_src sh
broot --only-folders
#+end_src
Filters out non-directory files from the view.
**** Advanced Usage
6. **Perform file operations within broot**
- Press `:rename` to rename a file.
- Press `:delete` to remove a file.
- Use `:move target_directory` to move a file.
7. **Find and open a file in an editor**
#+begin_src sh
broot --cmd "edit file_name"
#+end_src
Searches and opens a file using the default editor.
8. **Integrate broot with `cd` command**
#+begin_src sh
broot --install
#+end_src
Enables `br` to work as a replacement for `cd`.
9. **Customize broot settings**
#+begin_src sh
broot --edit-conf
#+end_src
Opens the broot configuration file for customization.
*** Customizing broot
**** Change default display options
#+begin_src sh
broot --set-default-flags "gh"
#+end_src
Sets the default view to show hidden files and a grid layout.
**** Define a shortcut for frequently used commands
#+begin_src sh
alias bcd='broot --cmd "cd"'
#+end_src
Creates an alias to quickly navigate directories.
*** Final Thoughts
- broot is a powerful alternative to `ls`, `tree`, and `cd`, offering an interactive way to browse and manage files.
- With fuzzy search and built-in file operations, it enhances productivity for command-line users.
- Customization options allow tailored keybindings and themes for better usability.