#+title: lesson 02 | course overview + the shell #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: * 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]] *current* + [[https://www.youtube.com/watch?v=kgII-YWo3Zw&t=2649s][44:09 - history substring search]] * 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