TLDR:
- devhints.io/bash (my prefered cheat sheet)
- shell check extention for vs code
- shellcheck
- shellharden
- more program examples
- Communicate with hardware.
- Run programs.
Programs are the real work horse, they can do anything.
- Text based OS interface.
- With heavy focus on the filesystem for hardware communication.
- Start programs.
- Read and write files.
- REPL (Read Evaluate Print Loop).
Your server/CICD has it. 🤖
Programs can compose in interesting ways. 💥
Write the name of the program.
# Print your current Working Directory
pwd
# List directory contents
ls
# Print environment
env
# Manual
man
# Read as much as you can see from a file
less
Optionally pass some arguments, almost like a function call in a programming language.
ls -l
man ls
less --help
Where programs are found.
# Show you mine
echo $PATH
# So, where is my program? _which_ program?
man which
which pwd
which ls
which env
/usr/bin/env
You are special. 🏠
echo $HOME
ls $HOME
ls ~
Others just require special help, from you. 🤷♂️
echo $JAVA_HOME
echo $GOPATH
Inputs and outputs, all mixed up.
cat
Files, files and more files. From every (re)direction.
cat < readme.md
cat > output_cat.txt
cat readme.md
Markdown
npm install -g marked
which marked
marked -h
marked
# H1
And a paragraph
Common convention, word "flags" have double --
, short "flags" (single letter) have one -
.
(Common, but anything goes)
marked --input readme.md
marked --input readme.md --output output_space.html
marked --input=readme.md --output=output_equal.html
marked -i readme.md -o output_short.html
marked < readme.md
marked < readme.md > output_redirected.html
cat readme.md | marked > output_redirected2.html
Wait, it was supposed to be files, not the internet?
# Download from github
curl https://api.github.com/users/pirfalt
# Save to file
curl https://api.github.com/users/pirfalt > users_pirfalt.json
# Was that an error?
curl https://api.github.com/users/pirfalt 2> users_pirfalt_error.json
# Yes, you can multi redirect
curl https://api.github.com/users/pirfalt > users_pirfalt.json 2> users_pirfalt_error.json
# And long lines can be broken
curl https://api.github.com/users/pirfalt \
> users_pirfalt.json \
2> users_pirfalt_error.json
Get the programs you don't have.
brew
brew list
docker run -it --rm ubuntu:20.04
echo $SHELL
env
curl
apt --help
apt update
apt install curl
curl
exit
Also on "linux" yum
(redhat, centos), apk
(alpine) ...
- https://docs.microsoft.com/en-us/windows/wsl/ 👌
- Just like linux.
- https://chocolatey.org/
¯\_(ツ)\_/¯
Bash starting more bash
bash -c 'cd ~ ; ls'
# ^ Thats new
Python
python -c 'import os; print(os.environ)'
NodeJS
node -e 'console.log(process.env)'
jq
cat users_pirfalt.json | jq '.'
cat users_pirfalt.json | jq '. | { login, location, company }'
cat users_pirfalt.json | jq '.repos_url'
man jq
cat users_pirfalt.json | jq -r '.repos_url'
curl $() # ??
cat readme.md | grep 'echo'
I still have to look it up, very often. devhints.io/bash.
variable_declaration_and_assignment="first"
echo "$variable_declaration_and_assignment"
single_quotes='includes: $variable_declaration_and_assignment'
echo "$single_quotes"
double_quotes="includes: $variable_declaration_and_assignment"
echo "$double_quotes"
no_quotes=includes:\ $variable_declaration_and_assignment
echo "$no_quotes"
# My own personal rule of thumb:
# Always use single quotes. Until you need double quotes.
# No quotes are problems waiting to happen.
# And use shellcheck/shellharden.
curl -H 'Accept: application/vnd.github.v3+json' https://api.github.com/users/pirfalt
# Call github with the correct headers
call_github() {
local args=$*
curl -H 'Accept: application/vnd.github.v3+json' $args
}
call_github https://api.github.com/users/pirfalt
# Start crawling
find_repos_for_user() {
local user="$1"
local user_url="https://api.github.com/users/$user"
local repo_url="$(call_github "$user_url" | jq -r '.repos_url')"
call_github "$repo_url" | jq '.[] | [ .name, .html_url ]'
}
find_repos_for_user pirfalt
# Late input
find_repos_for_user_v2() {
echo -n 'Please enter a username: '
read user
local user_url="https://api.github.com/users/$user"
local repo_url="$(call_github "$user_url" | jq -r '.repos_url')"
call_github "$repo_url" | jq '.[] | [ .name, .html_url ]'
}
find_repos_for_user_v2
Please don't. bash
can do if-then-else
logic. But it's messy. 🤷♂️
ls | while read file_name; do echo "Found: $file_name in this directory"; done
for f in $(ls); do echo "Found: $f in this directory"; done
for c in 1 2 3 4; do echo "space separated $c"; done
while true; do ls; sleep 2; done
echo '#!/bin/bash
echo "My script which lists files... and location"
echo ""
ls -al
echo ""
pwd
' > script.sh
./script.sh
chmod +x ./script.sh