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 mandisplays the manual page for themancommand.
man builtindisplays 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/pbpastewill copy/paste content into/from the clipboard
command1; command2- Runcommand2regardless of result ofcommand1command1 && command2- Runcommand2only ifcommand1is successfulcommand1 || command2- Runcommand2only ifcommand1is not successfulcommand1 | command2- Pipe the output fromcommand1tocommand2
How do we know if the command was successful? We can check the exit code.
0indicates 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:
UPwill scroll through the history in reverse chronological order.DOWNwill scroll through the history in chronological order.
CTRL+Pdoes the same asUP(P = previous).CTRL+Ndoes the same asDOWN(N = next).
!!will execute the previous command again.
What if the command you want to rerun is older?
historywill show you a list of all stored previous commands.HISTSIZEcontrols how many entries are stored.HISTTIMEFORMATcontrols 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:
!lswill 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- Replacesearchwithreplacefrom the previous command
reverse-i-search allows you to search through history based on substrings.
- Press
CTRL+Rto start searching. - As you type, the most recent match will be displayed.
- Press
CTRL+Ragain to see cycle through matches - Press
ENTERto execute, orBACKto edit. - Press
CTRL+Gto 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
bindirectory.
- 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.