The shell is a layer above the kernel and can be a command-line shell or a graphical shell. We're going to focus on command-line shells.
The Shell Command Language is a POSIX standard which has many implementations. Not all shells have the same functionality, so it's important to know what is common amongst all popular shells and what is unique to specific shells. sh
, bash
, csh
, zsh
are some common shells.
Shells include online manual pages, often referred to as man pages, due to the man
command which displays them.
man man
displays the manual page for theman
command.
man builtin
displays the manual page for the common built-in methods.- As mentioned before, the built-in methods are shell dependent.
- Examples of built-in methods:
alias
- basic string substitution for commandsenv
- display/create an environmentexport
- set a environment variablekill
- send a single to a running processpopd
/pushd
- traverse directories using a stackpwd
- print the working directorysource
- read and execute a file in the current shell contexttime
- measure how long a command takesunset
- remove variables and functions
cat
- concatenate and print the content of filescd
- change working directorygrep
- search files for texthead
- print the beginning of a file/streamless
- print content with paginationln
- link filesls
- list filessudo
- execute a command as another usertail
- print the end of a file/stream
pbcopy
/pbpaste
will copy/paste content into/from the clipboard
command1; command2
- Runcommand2
regardless of result ofcommand1
command1 && command2
- Runcommand2
only ifcommand1
is successfulcommand1 || command2
- Runcommand2
only ifcommand1
is not successfulcommand1 | command2
- Pipe the output fromcommand1
tocommand2
How do we know if the command was successful? We can check the exit code.
0
indicates success, while any other number indicates an error.- Exit codes are specific to the command being run.
$?
contains the exit code for the previous command
Shells have tools for working with the history of commands that have been run.
To rerun the most recent command, there are a few options:
UP
will scroll through the history in reverse chronological order.DOWN
will scroll through the history in chronological order.
CTRL
+P
does the same asUP
(P = previous).CTRL
+N
does the same asDOWN
(N = next).
!!
will execute the previous command again.
What if the command you want to rerun is older?
history
will show you a list of all stored previous commands.HISTSIZE
controls how many entries are stored.HISTTIMEFORMAT
controls the time formatting for when a command was run.- Try
HISTTIMEFORMAT='%F %T ' history
.
- Try
Any previous command can be executed based on its position in the history:
!{number}
- The command identified by{number}
.!-{number}
- The command run{number}
commands ago. (!-1
= most recent command)
Appending :p
to one of the !
history commands will print the command rather than executing it. The expanded command will be placed into the history again.
Previous commands can also be searched by prefix:
!ls
will rerun the most recent command that starts withls
.
The parameters from the previous command can be referenced individually.
!^
- The first parameter!$
- The last parameter!*
- All parameters!:{number}
- The paramter in position{number}
.^search^replace
- Replacesearch
withreplace
from the previous command
reverse-i-search
allows you to search through history based on substrings.
- Press
CTRL
+R
to start searching. - As you type, the most recent match will be displayed.
- Press
CTRL
+R
again to see cycle through matches - Press
ENTER
to execute, orBACK
to edit. - Press
CTRL
+G
to exit the search.
alias
- good for simple commandsfunctions
- good for longer commands and better for debugging- Custom executable files
- Most languages have the ability to create executables.
- Identify the interpreter via a shebang line (+1 optional argument).
- e.g.,
#!/usr/bin/env node
- e.g.,
- Add the executable to your
PATH
.- Easiest way is to symlink to a
bin
directory.
- Easiest way is to symlink to a
It's always a good idea to gracefully handle user input. Don't write scripts that require changes to the source code for multiple runs. Take in arguments as input from the user. This can be done via interactive prompts or via command line arguments.
For command line arguments, use an existing library for parsing and displaying help text.
Strategic use of colors can greatly improve the output of a program.
Colors are defined using escape sequences in the output. The escape sequence is comprised of four parts:
- Escape character - represented by
\e
,\x1b
, or\033
. - Control Sequence Introducer -
[
. - Color codes - prefix, color, and text decoration; delimited by
;
. - Finishing symbol -
m
Prefixes can expand color palettes to more than just the basic 16 colors, but we'll stick to the basics for now.
- Foreground
- 30 - Dark Gray
- 31 - Red
- 32 - Green
- 33 - Yellow
- 34 - Blue
- 35 - Purple
- 36 - Turquoise
- 37 - Light Gray
- Background
- 40 - Dark Gray
- 41 - Red
- 42 - Green
- 43 - Yellow
- 44 - Blue
- 45 - Purple
- 46 - Turquoise
- 47 - Light Gray
- 1 - bold
- 4 - underline
The PS1
environment variable controls the prompt string. You can put anything you want into the prompt.