docs/Los.md

Spent the hour starting the book Learn Bash The Hard Way to learn about Bash.


Built the game Pong in Python to touch up on my Python skills again. Revisted turtles, tkinter, and Docker. *Learned that:

  • Python not being a compiled language means I'll frequently run into issues with missing libs/pckgs when containerizing/working in virt envs

  • About the Turtle library and how it relates to tkinter

  • Adding sound in Python is very complicated because it's handled differently by each OS (damn you capitalism)


Continued building off my pong game. What I did:

  • Added a speed multiplier to the ball.

  • Added the ability to pass along player names.

  • Added randomization of ball projectory at start of each round.

Points of pain:

  • Still can't properly containerize the game due to an issue with tkinter/screen access in Docker

  • Starting to think containerizing anything that isn't vanilla Python isn't worth it


Continued Learn Bash The Hard Way. What I learned:

  • Two different ways to write a For loop: using C notation ( for (( i=0; i < 20; i++ ))) or using "in" ( for f in $(ls *txt) )

  • While loops exist and work like you'd expect them to

  • In case statements, double ; indicates when another case is being made (e.g. 1) echo 'a is 1'; echo 'ok';; 2) echo 'a is 2'; echo 'ok';; )

  • getopts is used often in cases


Continued Learn Bash The Hard Way. Learned about Exit Codes. What I learned:

  • About exit codes (e.g. 0 is success; 1 is general errror; 2 is miuse of builtin; 127 is cmd not found)

  • How to make a script use an explicit exit code by using 'return' (e.g. then echo 'matched!'; return 1; )

  • Special operators like $$ (gives you the process ID of the shell or the shell the invoked the subshell) and $! (gives you the process ID of the most recent bg job)


Continued Learn Bash The Hard Way. What I learned:

  • set is a builtin that tells you the state of your shell (i.e. all your vars and f(x)s set in your env)

  • posix mode ensures that set doesn't output any functions; you toggle it on with -o and off with +o

  • set vs env diff: env shows exported variables, not all vars set in the shell

  • The errexit option tells bash to exit the script if any command fails

  • xtrace option outputs each command as it is being run (useful for seeing what command was actually run in a script)

  • You can also us the flags set -e/ set -x for errexit/xtrace respectively

  • -o pipefail is used to return error code of last command to return a non-zero status;

  • Since grep returns non-zero even when there’s no ‘error’ as such, you can get surprising behaviour when using pipes and exit codes so pipefail is useful.


Continued Learn Bash The Hard Way. What I learned:

  • echo can take clags like '-n' (which makes sure it doesn't print a new line) or '-e' (which makes sure special chars are processed liked '\t') or '-E' (opp of '-e')

  • You can even echo specific byte value to the terminal by specifying its hex value (e.g. "echo -n -e '\x200\n'" --> 0 | or "echo -n -e '\x60\n'" --> `) which is useful for debugging/controlling exactly what gets sent to screen

  • CTRL+V escape characters are a thing (e.g. ^I means CTRL+V + CTRL+i)

  • Terminal Escape Codes like '-e \033[?47h' (saves but doesn't clear screen) or '-e \033[?47l' (restores what you saved from the screen)


Started the Odin Project to brush up my web dev skills and learn Rails


Continued Learn Bash The Hard Way. What I learned:

  • The PS1 var which is basically the prompt so you can customize what your bash prompt says or 'prompts' you to do

  • The PS2 var is ‘other’ prompt shell uses to indicate you're being prompted for input to a program that is running; basically use it for prompts that display while a program is running

  • PS4 is a var used best with Trace mode (prints ever cmd as it's run) so you can see PS4 being printed as each cmd is run (PS4 is echoed before each line of trace output)

  • You can customize your prompt using special escape chars like (" PS1='\u@\H:\w # $ ' " --> this creates the same prompt the default shell has)

  • 'PROMPT_COMMAND' is a var to also affect the prompt; Every time the prompt is displayed, PROMPT_COMMAND is treated as a command, and run.


Continued the Odin Project


Still doing the Odin Project. Really enjoying it so far.


Worked on the next chapter of Learn Bash The Hard Way. What I learned:

  • You don't need quotes to declare a string var: e.g. MYSTRING=astring echo $MYSTRING --> astring

  • Single quotes for vars means you don't actually call the var: e.g. MYSENTENCE='A sentence with MYSENTENCE --> A sentence with $MYSTRING in it

  • This is not true for globs (): e.g. MYGLOB="" echo $MYGLOB --> Everything in my current directory

  • When indexing arrays: I need curly brackets around the whole variable and index But the {BASH_VERSINFO[0]}

  • All simple vars in bash are really arrays with just 1 element in it

  • Commas are one way to iterate through an array: e.g. echo ${BASH_VERSINFO[0,5]} --> x86_64-pc-linux-gnu (returns elements 0-5)

  • Associative arrays are like dicts but look very messy; should prob avoid them


Finally figured out how to properly containerize one of my projects!!!!!!!


Cont the Odin Project. Made a small cookbook site out of it. It's very humble.


Continued Learn Bash The Hard Way to cover functions. What I learned:

  • vars have a global scope unless otherwise declared

  • to declare limited scope, use "local": e.g. function myfunc { local myvar="Hi from inside the function" echo myvar outside the function, it won't work because it only exists inside the function

  • “ cd - ” returns you to the previous directory you were in

  • use "builtin" to call functions built into Bash

    • Useful incase you make a function that conflicts in name with a builtin (like "func cd()")
    • With clashes, the function, not builtin is used
    • Use "unset -f name_of_func" to unset func name & remove the conflict (or "-v" to unset vars)
  • "declare -f" outputs all funcs in my env (including their code) while "declare -F" just lists the funcs names

  • Programs are executable files (think grep, vi, sed, etc)

  • you can use "which" to see if it's a builtin or a func: e.g. "which grep" --> /usr/bin/grep means it's a program/binary file, not a builtin) fun fact: which is a binary file/program, not a builtin

  • "alias" is a powerful tool for creating shortcuts to commands: e.g. "alias python='python3'" --> means that when I type "python", it'll open python3 for me

  • "typeset" and "declare" have the same functionality, typeset is just obsolete


Spent the day trying to containerize an old app/game I made. I learned that a library (Playsound) I used is very poorly maintained. I might need to give up or refactor the app with a different library. Currently, Playsound won't work in virtual envs (like Docker) because of the Gi module.


Spent the day going through git tutorials. Learned about rebasing vs merging (basic, I know) from a very cool resource (https://learngitbranching.js.org/). Hopefully, also managed to fix the issue that my PR caused on the BBT repo for 100 Days.


Continued Learn Bash The Hard Way to cover functions. What I learned:

  • Learned about the channels Std Error and Std Output

  • If you string cmds (e.g. cat file | grep -c file), if the first cmd outputs to Std Err, nothing is passed to the pipe cmd in this case

  • /dev/null is a special file created by Linux (and UNIX) kernels that's black hole into which data can be pumped; anything written to it will be absorbed and ignored.

  • The < operator redirects standard input to the command from a file e.g. grep -c file < file1 will pass file1 as input to the cmd grep

  • Using > will overwrite a file; using >> will append to it e.g. echo line2 > file3 echo line3 >> file3 --> cat file3 file3 | | --> line2 line3


Continued Learn Bash The Hard Way to cover scripts. What I learned:

  • A pipe passes ‘standard output’ as the ‘standard input’ to another command

  • A redirect sends a channel of output to a file

  • The < operator redirects standard input to the command from a file

  • How to set permissions using chmod


Continued Learn Bash The Hard Way to continue scripts and tests. What I learned:

  • You can't use '' to substitute commands in a script, you need "" (e.g. '$(hostname)' won't work)

  • You can use ticks though (e.g. "hi hostname" --> hi WayneTech-IdeaPad)'

  • You can nest commands like this: (cmd2 $(cmd3)))

  • Overall, () is easier to nest and read than ` because you have to escape \ with backslashes

  • $? can tell you if the last command failed (1) or not (0)

  • "[" is a builtin and a program and "[" and "test" are synonymous

  • You can write "and" and "or" as ||/-o and &&/-a respectively (e.g. [ 1 = 1 -o ! '0' = '0' -a '2' = '2' ]))

  • Use [[ as a safety net to tolerate cmds that don't exist (e.g. [[ ${DOESNOTEXIST} = '' ]] is evaluated as [ '' = '' ])

  • It's prob for the best to always use [[ to just be safe


Continued Learn Bash The Hard Way to continue scripts, conditionals, tests, unary and binary operators. What I learned:

  • I should probably use [[ always because it's such a good safety net (e.g. [ 10 < 2 ] doesn't work but [[ 10 < 2 ]] does because the former has < expecting a STRING, not int)

  • From the above, this means that type matters in bash so all the more reason to use [[

  • However things like -gt, -lt, -eq, -ne all work fine with a single [

  • You can make a single line script and use semi's to show new lines (e.g. if [[ 10 -lt 2 ]]; then echo 'does not compute'; fi )