289 lines
8.2 KiB
Org Mode
289 lines
8.2 KiB
Org Mode
|
|
#+title: lesson 02 | course overview + the shell
|
||
|
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="../_share/media/css/missing-semester.css" />
|
||
|
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="../_share/media/css/org-media-sass/collapsible.css" />
|
||
|
|
#+HTML_HEAD: <script src="../_share/media/js/collapsible.js"></script>
|
||
|
|
|
||
|
|
* 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]] *current*
|
||
|
|
+ [[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]]
|
||
|
|
|
||
|
|
* 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
|