So far we have used bash commands to navigate our file system as a way to learn about the file system itself. To do this we used commands like:
mvcdpwdlsfindrm
Solution to Exercise 1
command | explanation |
|---|---|
| print working directory |
| change directory to path |
| make a directory called name |
| list, show the files |
| create an empty file |
| repeat ‘message’ to stdout |
| write redirect |
| append redirect |
| remove (delete) |
| concatenate a file to standard out (show the file contents) |
| Moves file from path to another (can be used to rename only) |
| Copies the content of the file from into a new file (can be with or without the same name) |
| search the file system (paths) for matches to a pattern |
Bash is a unix shell for the GNU operating system and it has been adopted in other contexts as well. It is the default shell on Ubuntu linux as well for example (and many others). This is why we teach it.
A Unix shell is both a command interpreter and a programming language. As a command interpreter, the shell provides the user interface to the rich set of GNU utilities. The programming language features allow these utilities to be combined.
Read the official definition of bash and a shell in the bash manual
Inspecting an example script¶
Today we will start by inspecting the github action file, first we’ll navigate to the folder.
cd fall25-kwl-brownsarahm/We want to look at a file if we get this far and then press tab mulitple times, it will show us the options
cat .github/workflows/create_about.yml forgottenexperience.yml logger.yml
experienceinclass.yml getassignment.yml
experiencereport.yml label_badges.ymlThen we will look at the getassignmet one.
cat .github/workflows/getassignment.ymlname: Create badge issues (Do not run manually)
on:
workflow_dispatch
# once you edit, change the name
jobs:
check-contents:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
# Install dependencies
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Install Utils
run: |
pip install git+https://github.com/compsys-progtools/courseutils@main
- name: Get badge requirements
run: |
# prepare badge lines
pretitle="prepare-"$(cspt getbadgedate --prepare)
cspt getassignment --type prepare | gh issue create --title $pretitle --label prepare --body-file -
# review badge lines
rtitle="review-"$(cspt getbadgedate --review)
cspt getassignment --type review | gh issue create --title $rtitle --label review --body-file -
# practice badge lines
pratitle="practice-"$(cspt getbadgedate --practice)
cspt getassignment --type practice | gh issue create --title $pratitle --label practice --body-file -
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# edit the run step above for the level(s) you want.
# You should keep the prepare, because they are required for experience badges
# You may choose to get only the review or only the practice (and change this any time)nano .github/workflows/label_badges.ymlthen commit directly to main
git add .git commit -m 'turn on schedule'[main 3f55616] turn on schedule
1 file changed, 2 insertions(+), 2 deletions(-)and push
git pushEnumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 16 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 460 bytes | 460.00 KiB/s, done.
Total 5 (delta 3), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/compsys-progtools/fall25-kwl-brownsarahm.git
4714a02..3f55616 main -> mainVariables in Bash¶
The basic syntas is:
MYVAR=my_valwhere:
MYVARis the variable namemy_valis the value assigned to the variable
so for example:
NAME='sarah'A common mistake is to put a space around the = sign, this is actually considered good style in many other languages.
NAME = 'sarah'-bash: NAME: command not foundIn bash, however, this creates an error. When there is a space after NAME, bash tried to interpet NAME as a bash command, but then it does not find it, so it gives an error.
Removing the space works again:
NAME='sarah'we can use variables with a $ before the variable name.
echo $NAMEsarahEnvironment Variables¶
Environment variables are global.
A common one is the PATH. This variable is where your computer looks for programs to run when you call commands.
echo $PATH/Users/brownsarahm/miniforge3/condabin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Frameworks/Python.framework/Versions/3.13/binAnother is PS1, this sets your prompt
echo $PS1\u@\W \$This one sets my prompt to look like:
username@last_part_of_path $
so if my path is /Users/brownsarahm/Documents/inclass my prompt will read brownsarahm@inclass $
You can store environment variables to be set each time you start a terminal in your profile.
On MacOS this file is:
~/.bash_profileon linux it is
~/.baschrc
Variables are path independent¶
We can, however use the variable at different working directories. So if we move
cd ../gh-inclass-fa25-brownsarahm/and call it again
echo $NAMEsarahstill works !
The $ is essential syntax for recalling variables in bash. If we forget it, it treats it as a literal
echo NAMENAMEso we get the variable name out instead of the variable value
GH Actions as an example of scripts¶
Check out the github action marketplace to see other actions that are available and try to get a casual level of understanding of the types of things that people use actions for.
Bash Loops¶
We can also make loops like
for loopvar in list
do
# loop body
echo $loopvar
doneSo, for example:
for name in Sarah Karter Kevin> do
> echo $name
> done
Sarah
Karter
KevinNotes:
The
>is not typed, it is what happens since the interpreter knows that after we write the first line, the command is not complete.a list in bash is items with spaces, no brackets here
When we get the command back with the up arrow key, it puts it all on one line, because it was one command. The ; (semicolon) separates the “lines”
for name in Sarah Karter Kevin Jack Ayman; do echo $name; doneSarah
Karter
Kevin
Jack
AymanNesting commands¶
We can run a command to generate the list by putting it inside $() to run that command first. Think kind of like PEMDAS and the $ in bash is for variables.
for file in $(ls)
> do
> echo $file
> done
README.mdthe $() tells bash to run that command first and then hold its output as a variable for use elsewhere
We can modify what is in the $():
for file in $(ls -a); do echo $file; done.
..
.git
.github
.secret
README.mdConditionals in bash¶
We can also do conditional statements
if test -f docs\> then
> echo "file"
> fi
-bash: syntax error near unexpected token `fi'I made a typo, pressing \ instead of . To figure out what happened and understand that error, I used the up arrow key to get back the command:
if test -f docsthen; echo "file"; fithe \ is interpetted as nothing so then without the then keyword the fi is a syntax error
I tried to fix it by adding a ; after docs
if test -f docs; then; echo "file"; fi-bash: syntax error near unexpected token `;'this was still an error, so I retyped the whole thing:
if test -f docs
> then
> echo "file"
> fiand used the up arrow here
if test -f docs; then echo "file"; fiI learned that the then keyword can be on its own line visually, but it is not a full line that can be separated with ;
To recall, the correct if is
if test -f docs
> then
> echo "file"
> fithe key parts of this:
testchecks if a file or directory existsthe
-foption makes it check if the item is a filewhat to do if the condition is met goes after a
thenkeywordthe
fi(backwardsif) closes the if statment
This outputs nothing because docs doesn’t exist, but we can switch branches:
git checkout organizationPrevious HEAD position was 99f86bf create a readme closes #1
Switched to branch 'organization'
Your branch is up to date with 'origin/organization'.if test -f docs; then echo "file"; fiNow it outputs nothing because docs is a directory not a file.
If we switch it, we get output:
if test -f API.md; then echo "file"; fifileScript files¶
We can put bash commands into a file to make them a script
nano filecheck.shecho "hello world"and run it with bash <filename>
bash filecheck.shhello worldPrepare for Next Class¶
In fractionalbinary.md use 8 bits to represent the following numbers by using 4 bits as usual (8,4,2,1) and the other 4 bits are 1/2, 1/4, 1/8, 1/16th:
1.5
12.75
7.5625
15.9375
Add to your file some notes about the limitations of representing non integer values this way. How much would using more bits help with, what limitations are not resolved by adding more bits. For example, how could you represent .1?
Badges¶
Review the notes from today
Update your KWL Chart learned column with what you’ve learned
write a bash script to make it so that
cating the the files in yourgh_inclassrepo does not make the prompt move
Review the notes from today
Update your KWL Chart learned column with what you’ve learned
prevent
badges.jsonandbadges.ymlfrom being tracked by git in your kwl repowrite a bash script that prevents
jupyter-bookfrom giving warnings about files not having a heading by using the file name as a temporary title. (see the previous badge where you should have converted your repo, or do that one first, this counts as an extension on that if you have not done it)
Hint: Use sed’s insert option and head as needed.
Explore idea¶
modify your script to use a small llm from ollama to automatically insert a sensible title by summarizing the file. using a commercial chat interface does not qualify, but using an llm locally does