# Shell
|  | A **Command-line interface** (CLI) is a means of interacting with a computer program by inputting lines of text called command-lines. Command-line interfaces emerged in the mid-1960s, on computer terminals, as a user-friendly alternative to punched cards. |
| ---- | ---- |
| | wikipedia:: [Command-line interface](https://en.wikipedia.org/wiki/Command-line_interface) |
|  | In computing, a shell is a computer program that exposes an operating system's services to a human user or other programs. In general, operating system shells use either a command-line interface (CLI) or graphical user interface (GUI), depending on a computer's role and particular operation. It is named a shell because it is the outermost layer around the operating system. |
| | wikipedia:: [Shell (computing)](https://en.wikipedia.org/wiki/Shell_(computing)) |
## Meta shell
### Help
- man
- Search all the man pages for a keyword
- man -k searchTerm
- e.g.
- man -k directory
- views all of the man pages related to the command directory such as mkdir, ls, etc.
- man man
- man intro
- good intro guide to the command line
- man bash
- From Inside the man page
- /searchTerm
- searches inside that man page
- n
- goes to the next found term
- --help?
- help
- apropos - searches for man pages related to that command
- whatis
- description of what the command does
- info
- compgen -c
- Lists all available commads
### Terminal multiplexers
- [[tmux]]
- screen
### [[Shell on macOS]]
### [[Shell Scripting]]
### [[Cron]]
### [[Shell `at`, `batch`, `atq`, and `atrm` commands for scheduling]]
### Comments
- `# comment`
## Environment
- Each time we launch the terminal application, it creates a new session. The session immediately loads settings and preferences that make up the command line environment.
- We can configure the environment to support the commands and programs we create. This enables us to customize greetings and command aliases, and create variables to share across commands and programs.
- The environment refers to the preferences and settings of the current user.
### Sessions
### [[Shell Environment Variables]]
### Path/Directory
- PWD
- which
- shows the path to that command - where the actual binary is located as determined by $PATH environment variable
- which python3
- which ls
### General syntax of commands
- Broadly, there is a command and then maybe various arguments. The arguments can then be further broken down into options/switches/flags, parameters, and targets.
- | - | |
- <> are often used in Syntax guides to indicate that the <> surround a place for a command rather than an actual command. | is used to denote OR or Optional so in the line above we read that a Command can be used on its own but may be followed by Switches (single letters, preceded by a hyphen that adjust what the command does), Parameters (Things that the command needs to know in order to work) and a Target (The thing that the command will be applied to).
- switches aka options aka flags
- often work either shorthand with one dash -U or with a full name -user
- Evaluate to Boolean
- Shorthand -a
- Longhand --all
- e.g.
ls -l /home/brian
- means List in Long Format (the -l switch) the directory (target) /home/brian
### Exit
- exits terminal
### Keyboard commands
- Tab
- Autocomplete partially typed commands, files, etc.
- If there are multiple possibilities, tab won’t complete, but if you double tap tab you’ll get a list of the possibilities
- Good for finding the names of options and switches
- Good for finding all the apps that start with a set of letters with apt-get install for example
- Up arrow
- Cycles through previous inputs
- Ctrl - C
- Halts the current command, cancel the current operation and/or start with a fresh new line - sends a sigint
- q
- quits a terminal mode, like in less, e.g. - Ctrl-c doesn’t work in less. I think it might be in vi or something
- Ctrl - Z
- Stops the current command, resume with fg in the foreground or bg in the background
- Ctrl - R
- Recent commands
- Can search them as well?
- Ctrl - L
- Clears the screen leaving your typing there
- Equivalent to the clear BASH command
- Ctrl-D
- Exits the shell
- Ctr-alt-del
- REISUB
- Ctrl-A
- Cursor to start of line
- Ctrl-E
- Cursor to end of line
- Ctrl-U
- Cut/Delete left of cursor
- Ctrl-K
- Cut/Delete right of cursor
- Ctrl-W
- Cut/Delete word to left of cursor
- Ctrl-Y
- Paste what you cut via Ctrl-U or K or W
### $
- Dollar prompt
### \#
- Shown at prompt when root
### !!
- Repeats last command
- E.g. If you forget sudo you could just type "sudo !!"
### !$
- Repeats just the last argument
- E.g.
- Mkdir \~/docs/Evan
- Cd !$
### &
- after last command to tell terminal to run it in the background, thus freeing up the currnet terminal for further use
- e.g.
- sudo apt-get upgrade &
- ping google.com & ping apple.com &
- runs both commands in background
- It will output a process id number which you can check later with ps or kill with kill
- You can keep doing this indeifintely with multiple commands to be sent as a background process
### History
- Up Arrow
- cycles through previous terminal commands
- history
- command to list your terminal history
- !num
- !53
- executes specific numbered command
- !num:p
- To edit a command from history
- This prints the comnand instead of executing it so that you can then arrow up to edit it
- history with datestamps
- $ HISTTIMEFORMAT="%F %T " $ history
- This is only valid for the current session, but you can also add this to your bash profile if you want that to be permanent
- sudo !! trick to repeat last command with sudo prepended
- omnioutliner:///open?row=dOpCUN901UY
### Recursion
- -r or -R
- changes attributes of all files inside a folder instead of just the folder itself
### -y
- automatically answers yes to following confirmations
### Clear
- Clears everything on the screen
- equivalent to the ctrl-L keyboard shortcut
### Pause output per screen
- less
- usually per line?
- a pun on more
- q to quit
- I think it runs in vi
- more
- usually per page?
- you have to pipe the commands output to less or more
### Shells
#### Change shells
- chsh -s /bin/zsh
#### Display current shell
- echo $0
- echo $SHELL
#### [[Bash]]
#### [[Zsh]]
#### [[fish]]
#### [[dash]]
#### Sh
- https://en.wikipedia.org/wiki/Bourne\_shell
#### Ash
- https://en.wikipedia.org/wiki/Almquist\_shell
- Almquist shell
## Functions
- Example
- function hello { echo Hello! } $ hello
## Reference
### Variables
- Variables in functions are global by default unless declared local with local variablename=value
- A variable in bash can contain a number, a character, a string of characters. You have no need to declare a variable, just assigning a value to its reference will create it.
- Variables need to be preceded by $ when referencing them, but not when assigning them.
- Variable names are case-sensitive
- Variables are global by default, even in functions. local var=value declared it as local
- Example
- STR="Hello World!" echo $STR
- Delete Variable
- unset variable\_name
- $1 takes the value of the first argument after the script automatically
### [[Shell Environment Variables]]
## Data types
No actual data types
### Strings
#### "" Vs ''
- " " allows referencing other variables and command outputs whereas '' just sets whatever characters are in the quotes
- ""
- ''
#### End of file thing: `<< EOF`
- [linux - How does "cat << EOF" work in bash? - Stack Overflow](https://stackoverflow.com/questions/2500436/how-does-cat-eof-work-in-bash)
- Assign multi-line string to a shell variable
```bash
$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'
EOF
)
```
- The $sql variable now holds the new-line characters too. You can verify with echo -e "$sql".
- Pass multi-line string to a file in Bash
```bash
$ cat <<EOF > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
EOF
```
- The print.sh file now contains:
```bash
#!/bin/bash
echo $PWD
echo /home/user
```
- Assign multi-line string to a shell variable
```bash
$ sql=$(cat <<EOF
SELECT foo, bar FROM db
WHERE foo='baz'
EOF
)
```
- The `$sql` variable now holds the new-line characters too. You can verify with `echo -e "$sql"`._
- Pass multi-line string to a file in Bash
```bash
$ cat <<EOF > print.sh
#!/bin/bash
echo \$PWD
echo $PWD
EOF
```
The `print.sh` file now contains:
```bash
#!/bin/bash
echo $PWD
echo /home/user
```
## Data structures
### [[Shell Text Processing]]
#### [[Shell Wildcards]]
#### [[Regular Expressions|RegEx]]
### Arrays
- ARRAYNAME=(value1 value2 .... valueN)
- ARRAYNAME\[INDEXNR\]=value
- \* or @ means all elements of the array
- echo ${ARRAYNAME\[\*\]} or echo ${ARRAYNAME\[@\]}
## Control flow
### [[Shell Standard In, Standard Out, Standard Error]]
### [[Nix Services, Processes, & init System]]
### Piping
- |
- e.g.
- cat bands.txt | wc
- cat bands.txt | sort | grep The\*
- Ignore error for a given command
[linux - Bash ignoring error for a particular command - Stack Overflow](https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command)
`a_command | true`
- xargs
- "The xargs command in UNIX is a command line utility for building an execution pipeline from standard input. Whilst tools like grep can accept standard input as a parameter, many other tools cannot. Using xargs allows tools like echo and rm and mkdir to accept standard input as arguments."
- execute arguments
- echo 'one two three' | xargs mkdir ls one two three
- "By default xargs reads items from standard input as separated by blanks and executes a command once for each argument. In the following example standard input is piped to xargs and the mkdir command is run for each argument, creating three folders."
### Redirection
- >
- Instead of output going to screen it goes to a file
- e.g.
- ls -l Documents > documents.txt
- sort < bands.txt
- sort < bands.txt > bands_sorted.txt
- >> makes the output appended to the file instead of overwriting
- <
- goes the other way
- redirects stdin instead of stdout?
- e.g.
- cat gymnastics.txt is the same as cat < gymnastics.txt
- cat volcanoes.txt | wc | cat > islands.txt
### Multiple commands
- Order matters
- commands are interpreted in order
- Multiple Commands with Operators
- &&
- run second command only if first command completes successfully
- Ie, && is boolean so it requires both to be ‘true’
- e.g.
sudo apt-get update -y && sudo apt-get upgrade -y || echo “Something
went wrong”
- ||
- run second command only if first command doesn’t complete successfully
- Ie, boolean logic
- you can try using || to echo something to report if the previous sequence ran successfully - like { command && command } || echo something went wrong
- ;
- run second command regardless of if first command completes successfully
- ie, just a simple sequence, in order
- {} Brace Expansion #remember
- to group commands together like parentheses in logic
- e.g.
- command && echo command ran correctly || { echo command did not run correctly; commandtodointhatcase; }
- need a space between the curly brackets
- need ; at end of last command to return to shell correctly
- Better example:
- `cp {main.js,manifest.json} $obsidianVault/.obsidian/plugins/obsidian-wikipedia-data/"`
- instead of having 2 separate cp commands, this will effectively do 2 cp commands - 1 for each item in the braces.
- Multiple Commands with Conditionals
- if
- then
- else
- fi
- e.g.
- if ls \*.txt ; then echo We’ve found text files ; else echo No files found ; fi
- Chain Commands with ;
- touch file; sleep 10; rm file <-- 10 seconds
### [[Shell Conditionals]]
### Iteration
#### Loops
- For Loops
- Collection Traversal
- seq method is outdated
- for i in \`seq 1 10\`; do echo $i done
- for i in $( ls ); do echo item: $i done
- for i in {1...3} do echo $i done
- While Loops
- Example
- count=0 while \[ $count -lt 100 \]; do echo $count let count=count+1 done
- Until Loops
- Like while loop but in reverse, basically. But I think you can just use boolean ! to get the same thing?
- Example
- COUNTER=20 until \[ $COUNTER -lt 10 \]; do echo COUNTER $COUNTER let COUNTER-=1 done
- Syntax
- C, C++, Java like syntax \#issue
- start=4
- end=12
- jump=4
- for (( i = $start ; i <= $end ; i += $jump ))
- do
- echo $i
- done
### Exception/Error Handling
#### [[Nix Services, Processes, & init System]]
#### Interrupts
[How Linux Signals Work: SIGINT, SIGTERM, and SIGKILL](https://www.howtogeek.com/devops/linux-signals-hacks-definition-and-more/)
Software interrupts on Linux and Unix systems are made via signals. one can pass a signal to a running program or service to interact with it.
- Shell Signals
- HUP
- INT
- QUIT
- ILL
- TRAP
- ABRT
- EMT
- FPE
- KILL
- BUS
- SEGV
- SYS
- PIPE
- ALRM
- TERM
- URG
- STOP
- TSTP
- CONT
- CHLD
- TTIN
- TTOU
- IO
- XCPU
- XFSZ
- VTALRM
- PROF
- WINCH
- INFO
- USR1
- USR2
- The basic Linux signals all have a number (1-30+)
- A number of signals can be captured and redirected by the process, whereas others cannot - e.g. 9/kill
- SIGTERM
- 15
- may be ignored
- SIGKILL
- 9
- forces termination
- only use if needed - if hanging
- SIGINT
### Program termination
- [[kill (command)]]
- [[exit (command)]]
### Pause execution
- [[sleep (command)]]
### Commands
- [[pkill (command)]]
- [[caffeinate (command)]]
- [[Timeout (command)]]
- [[watch (command)]]
## Quantitative
### Operators
- &&
- ||
- -gt
- -lt
- -ge
- -le
- -eq
- -ne
- =
- !=
- !
- e.g.
- rm -r !(\*.txt)
- delete all files except for txt files
- `$(aCommand)` shell operator
- The `$(...)` shell operator executes the command within parentheses and substitutes its output into the command line.
- e.g.:
- `docker rm -vf $(docker ps -a -q)`
### Math & science
- bc
- calculator
### Date & time
## Io
### [[Shell Standard In, Standard Out, Standard Error]]
### Input
### Output
#### Echo
- [How to use Echo Command in Linux (With Examples)](https://phoenixnap.com/kb/echo-command-linux)
- echo string to print
- Normally quotes are unnecessary
- echo -E to echo the interpretation of escape chars. E.g. if you want actual \n instead of a new line.
- echo “Hello world!”
- Prints what is in quotes
- -e
- Allows you to use special characters
- e.g.
- echo “First line/nSecond Line/nThird Line”
#### Printf
#### Cat
- cat file1
- text files: displaying them, combining copies of them and creating new ones.
- cat <-> \#issue
- good for exploring files since its non-destructive
- e.g.
- cat file1 file2 > file3
- concatenates file1 and file2 together in file3
- cat file1 | less
- displays contents of file1 on screen and pauses before each screen advance
- cat file1 file2 file 3 | sort > file 4
- concatenates file1, file2, and file3, pipes it to the sort filter which alphabetizes each line before it is written to file4
#### Tac
- cat in reverse
- last line first, through to the first line.
#### Head
- displays top of text file
- defaults to 10 lines
- head -3 3 lines, etc.
#### Tail
- displays bottom of text file
- defaults to 10 lines
- tail -5 5 lines, etc.
#### Less
- sort of more sophisticated version of cat
#### More
#### Fold
- Wraps text
- fold -w5 myfile.txt > newfile.txt
- Wraps the lines of myfile.txt to a width of 5 characters, and writes the output to newfile.txt.
#### Colors and text effects
- echo -e "\\033\[31m Hello World"
- I think needs a Bash upgrade on macOS
- \[31m controls the text color
- 30-37 sets foreground color
- 40-47 sets background color
- -e allows escaped characters
### Ui
- [[ncurses]]
- Zenity
### Graphics
- scrot
screenshot tool - works in terminal
### Multimedia
- speaker-test
- tests the default audio device by playing tones
- aplay \#issue
- plays a sound file
- espeak
- text to speech?
- mplayer \#issue
- omxplayer
- imagemagick
- Can make gifs e.g.
- Find / -name \*.wav -exec aplay {} \\; \#issue
- (Plays all wav files it can find)
### Files
## Tools
- [[Homebrew]]
- [[Windows Subsystem for Linux]]
- [[Git Bash]]
- [[PowerShell]]
- [[NirCmd]]
- [[Zsh]]
- [[Midnight Commander]]
## Sources
## Inbox
- -e name
- Does a file named name exist in the working directory
- -d name
- is the fike named name a directory?
- [[Shellcheck (script SCA checker)]]
- [12 Factor CLI Apps. CLIs are a fantastic way to build… | by Jeff Dickey | Medium](https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46)
- [ralish/bash-script-template: A best practices Bash script template with several useful functions](https://github.com/ralish/bash-script-template)