Bash Cheat Sheet: Tips and Tricks for the Terminal

Ba$h Cheat Sheet

Our cheat sheet will help you efficiently navigate and control your system from the command line. From understanding file types and permissions to debugging, from controlling jobs to understanding regular expressions, this cheat sheet will have you covered.

The information in this cheat sheet is valuable to casual Linux and Mac users, system administrators, information security professionals, and students preparing for a wide range of exams, from the LPIC to the OSCP and beyond.

However you choose to use it, we hope you’ve found it a helpful resource to keep around. Click here to download a copy now. When you’re ready, scroll down, and let’s get into it!

Bash Cheat Sheet Search

Search our Bash cheat sheet to find the right cheat for the term you're looking for. Simply enter the term in the search bar and you'll receive the matching cheats available.

What Is Bash?

Bash (Bourne Again Shell) is a shell language built on top of the original Bourne Shell, which was distributed with V7 Unix in 1979 and became the standard for writing shell scripts. 

Today it is primary to most Linux distributions (see our Linux Command Line Cheat Sheet), MacOS, and it has even recently been enabled to run on Windows through something called WSL (Windows Subsystem for Linux).

File Test Operators

Testing files in scripts is easy and straightforward. This is where shell scripting starts to show its glory! In Bash, you can do file testing for permissions, size, date, file type, or existence.

-eFile exists
-aFile exists (identical to -e but is deprecated and outdated)
-fFile is a regular file (not a directory or device file)
-sfile is not zero size
-dfile is a directory
-bfile is a block device
-cfile is a character device
-pfile is a pipe
-hfile is a symbolic link
-Lfile is a symbolic link
-Sfile is a socket
-tfile (descriptor) is associated with a terminal device; this test option may be used to check whether the stdin [ -t 0 ] or stdout [ -t 1 ] in a given script is a terminal
-rfile has read permission (for the user running the test
-wfile has write permission (for the user running the test)
-xfile has execute permission (for the user running the test)
-gset-group-id (sgid) flag set on file or directory
-uset-user-id (suid) flag set on file.
-ksticky bit set.
-Oyou are owner of file
-Ggroup-id of file same as yours
-Nfile modified since it was last read
f1 -nt f2file f1 is newer than f2
f1 -ot f2file f1 is older than f2
f1 -ef f2files f1 and f2 are hard links to the same file
!  Not – reverses the sense of the tests above (returns true if condition absent).

Integer Comparison Operators

How to compare integers or arithmetic expressions in shell scripts.

-eqis equal to
-neis not equal to
-gtis greater than
-geis greater than or equal to
-ltis less than
-leis less than or equal to
<is less than – place within double parentheses
<=is less than or equal to (same rule as previous row)
>is greater than (same rule as previous row)
>=is greater than or equal to (same rule as previous row)

String Comparison Operators

String comparison in Bash.

=is equal to
==same as above
!=is not equal to
<is greater than ASCII alphabetical order
>is greater than ASCII alphabetical order
-zstring is null (i.e. zero length)
-nstring is not null (i.e. zero length)

Compound Operators

Useful for boolean expressions and is similar to && and ||. The compound operators work with the test command or may occur within single brackets [ <expr> ].

-alogical and
-ological or

Job Identifiers

Job control allows you to selectively stop (suspend) the execution of processes and continue their execution at a later point in time.

%NJob number [N]
%SInvocation (command-line) of job begins with string S
%?SInvocation (command-line) of job contains within it string S
%%"current" job (last job stopped in foreground or started in background)
%+"current" job (last job stopped in foreground or started in background)
%-Last job
%!Last background process

List Constructs

Provides a means of processing commands consecutively and in effect is able to replace complex if/then/case structures.

&&and construct
||or construct

Reserved Exit Codes

Useful for debugging a script. Exit takes integer args in the range 0-255.

1Catchall for general errors
2Misuse of shell builtins
126Command invoked cannot execute
127Command not found
128Invalid argument to exit
128+nFatal error signal "n"
130Script terminated by Control-C


UNIX System V Signals.

SIGHUP1exitHangs up
SIGQUIT3core dumpQuits.
SIGILL4core dumpIllegal instruction.
SIGTRAP5core dumpTrace trap.
SIGIOT6core dumpIOT instruction.
SIGEMT7core dumpMT instruction.
SIGFPE8core dumpFloating point exception.
SIGKILL9exitKills (cannot be caught or ignored).
SIGBUS10core dumpBus error.
SIGSEGV11core dumpSegmentation violation.
SIGSYS12core dumpBad argument to system call.
SIGPIPE13exitWrites on a pipe with no one to read it.
SIGALRM14exitAlarm clock.
SIGTERM15exitSoftware termination signal.

Sending Control Signals

You can use these key-combinations to send signals.

Ctrl+CThe interrupt signal, sends SIGINT to the job running in the foreground.
Ctrl+YThe delayed suspend character. Causes a running process to be stopped when it attempts to read input from the terminal. Control is returned to the shell, the user can foreground, background or kill the process. Delayed suspend is only available on operating systems supporting this feature.
Ctrl+ZThe suspend signal, sends a SIGTSTP to a running program, thus stopping it and returning control to the shell.

Check your stty settings. Suspend and resume of output is usually disabled if you are using "modern" terminal emulations. The standard xterm supports Ctrl+S and Ctrl+Q by default.

File Types

This is very different from Windows but straight forward once you get it. I'll expand this section soon with more context.

Regular file
l(Symbolic) Link
cCharacter device
pNamed pipe
bBlock device


Now you may know what that arcane looking string rwxrwxrwx is when you invoke ls -l

ssetuid when in user column
ssetgid when in group column
tsticky bit
0——The access right that is supposed to be on this place is not granted.
4—–rread access is granted to the user category defined in this place
2—–wwrite permission is granted to the user category defined in this place
1—–xexecute permission is granted to the user category defined in this place
uuser permissions
ggroup permissions
oothers permissions

Special Files

Files that are read by the shell. Listed in order of their execution.

/etc/profileExecuted automatically at login
Whichever is found first is executed at login.
~/.bashrcIs read by every nonlogin shell.

String Manipulation

Bash supports a surprisingly big number of string operations! Unfortunately, these tools lack a unified focus. Some are a subset of parameter substitution, and others fall under the functionality of the UNIX expr command. This results in inconsistent command syntax and overlap of functionality.

MacOS built-in bash is from 2007 and won't support many of these.

${#var}Find the length of the string
${var%pattern}Remove from shortest rear (end) pattern
${var%%pattern}Remove from longest rear (end) pattern
${var:position}Extract substring from $var at $position
${var#pattern}Remove from shortest front pattern
${var##pattern}Remove from longest front pattern
${var/pattern/string}Find and replace (only replace first occurrence)
${var//pattern/string}Find and replace all occurrences
${!prefix*}Expands to the names of variables whose names begin with prefix.
${var,}${var,pattern}Convert first character to lowercase.
${var,,}${var,,pattern}Convert all characters to lowercase.
${var^}${var^pattern}Convert first character to uppercase.
${var^^}${var^^pattern}Convert all character to uppercase.
${string/substring/replacement}Replace first match of $substring with $replacement
${string//substring/replacement}Replace all matches of $substring with $replacement
${string/#substring/replacement}If $substring matches front end of $string, substitute $replacement for $substring
${string/%substring/replacement}If $substring matches back end of $string, substitute $replacement for $substring
expr match “$string” ‘$substring’Length of matching $substring* at beginning of $string
expr “$string” : ‘$substring’Length of matching $substring* at beginning of $string
expr index “$string” $substringNumerical position in $string of first character in $substring* that matches [0 if no match, first character counts as position 1]
expr substr $string $position $lengthExtract $length characters from $string starting at $position [0 if no match, first character counts as position 1]
expr match “$string” ‘($substring)’Extract $substring*, searching from beginning of $string
expr “$string” : ‘($substring)’Extract $substring* , searching from beginning of $string
expr match “$string” ‘.*($substring)’Extract $substring*, searching from end of $string
expr “$string” : ‘.*($substring)’Extract $substring*, searching from end of $string

Bash Shell Command Generator

Say goodbye to the hassle of trying to remember the exact syntax for your Bash commands! With our Bash Shell Command Generator, you can simply say what you need Bash to do, and we will generate the command for you.


The following text shows characters or that need to be quoted if you want to use their literal symbols and not their special meaning.

;Command seperator
&Background execution
()Command grouping
< > &Redirection symbols
? [ ] ~ + – @ !Filename metacharacters
” ‘Used in quoting characters
$Variable, command or arithmetic substituion
#Start a command that ends on a linebreak
space tab newlineWord seperators

Everything between "..." is taken literally, except $ (dollar) ` (backtick) and " (double-quotation).

Everything between '...' is taken literally, except ' (single-quote).

The characters following is taken literally. Use to escape anything in "..." or '...'

Using $ before "..." or '...' causes some special behavior. $"..." is the same as "..." except that locale translation is done. Likewise, $'...' is similar to $'...' except that the quoted string is processed for escape sequences.

Command Parameters

Command parameters, also known as arguments, are used when invoking a Bash script.

$0Name of the script itself
$1 … $9Parameter 1 … 9
${10}Positional parameter 10
$*Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter seperated by the first of the IFS environment variable
$-Current options
$_The underscore variable is set at shell startup and contains the absolute file name of the shell or script being executed as passed in the argument list. Subsequently, it expands to the last argument to the previous command, after expansion. It is also set to the full pathname of each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.
$$Process id of the shell
$?Exit status of the most recently executed command
$@All arguments as separate words
$#Number of arguments
$!PID of most recently backgrounded process

History Expansion

Enables use and manipulation of previous commands.

!Starts a history substitution
!!Refers to the last command.
!nRefers to the <n>-th command line.
!-nRefers to the current command line minus <n>.
!stringRefers to the most recent command starting with <string>
!?string?Refers to the most recent command containing <string> (the ending ? is optional)
^string1^string2^Quick substitution. Repeats the last command, replacing <string1> with <string2>.
!#Refers to the entire command line typed so far.

Variable Operations

Perform operations on variables.

Get default shell variables value
Set default shell variables value
${parameter:?”Error Message”}
Display an error message if parameter is not set

Bash Globing

Bash cannot recognize RegEx but understand globbing. Globbing is done to filenames by the shell while RegEx is used for searching text.

*Matches zero or more occurences of a given pattern
?Matches zero or one occurences of a given pattern
+Matches one or more occurences of a given pattern
!Negates any pattern matches — reverses the pattern so to speak

Regular Expressions

Always use quotes in your RegEx to avoid globbing

.Matches any single character.
?The preceding item is optional and will be matched, at most, once.
*The preceding item will be matched zero or more times.
+The preceding item will be matched one or more times
{N}The preceding item is matched exactly N times.
{N,}The preceding item is matched N or more times.
{N,M}The preceding item is matched at least N times, but not more than M times.
Represents the range if it's not first or last in a list or the ending point of a range in a list.
^Matches the empty string at the beginning of a line; also represents the characters not in the range of a list.
$Matches the empty string at the end of a line.
[aoeiAOEI]Matches any 1 character from the list.
[^AOEIaoei]Matches any 1 character, not in the list!
[a-f]Matches any 1 character in the range a-f

In basic regular expressions the metacharacters "?", "+", "{", "|", "(", and ")" lose their special meaning; instead use the backslash versions "?" ... ")". Check in your system documentation whether commands using regular expressions support extended expressions.

Character Classes In BRE

A character class [:CharClass:] is a set of predefined patterns and comprpised of the following:

[:lower:][a-z]Lowercase letters.
[:upper:][A-Z]Uppercase letters
[:alpha:][A-Za-z]Alphabetic letters, both upper- and lowercase.
[:digit:][0-9]Numbers 0-9.
[:alnum:][a-zA-Z0-9]Alphanumeric: both letters (upper- + lowercase) and digits.
[:xdigit:][0-9A-Fa-f]Hexadecimal digits.
[:space:][ \t\n\r\f\v]Whitespace. Spaces, tabs, newline and similar.
[:punct:]Symbols (minus digits and letters).
[:print:][[:graph] ]Printable characters (spaces included).
[:blank:][ \t]Space and tab characters only.
[:graph:][^ [:cntrl:]]Graphically printable characters excluding space.
[:cntrl:]Control characters. Non-printable characters

Shell Built-ins

Shell builins are built into Bash are often very (if not extremely) fast compared to external programs. Some of the builtins are inherited from the Bourne Shell (sh) — these inherited commands will also work in the original Bourne Shell.

:Equivalent to true.
.Reads and executes commands from a designated file in the current shell.
[Is a synonym for test but requires a final argument of ].
aliasDefines an alias for the specified command.
bgResumes a job in background mode.
bindBinds a keyboard sequence to a read line function or macro.
breakExits from a for, while, select, or until loop.
builtinExecutes the specified shell built-in command.
callerReturns the context of any active subroutine call
cdChanges the current directory to the specified directory.
commandExecutes the specified command without the normal shell lookup.
compgenGenerates possible completion matches for the specified word.
completeDisplays how the specified words would be completed.
continueResumes the next iteration of a for, while, select, or until loop.
declareDeclares a variable or variable type.
dirsDisplays a list of currently remembered directories.
disownRemoves the specified jobs from the jobs table for the process.
echoDisplays the specified string to STDOUT.
enableEnables or disables the specified built-in shell command.
evalConcatenates the specified arguments into a single command, and executes the command.
execReplaces the shell process with the specified command.
exitForces the shell to exit with the specified exit status.
exportSets the specified variables to be available for child shell processes.
fcSelects a list of commands from the history list.
fgResumes a job in foreground mode.
getoptsParses the specified positional parameters.
hashFinds and remembers the full pathname of the specified command.
helpDisplays a help file.
historyDisplays the command history.
ifUsed for branching.
jobsLists active jobs.
killSends a system signal to the specified process ID (PID).
letEvaluates each argument in a mathematical expression.
localCreates a limited-scope variable in a function.
logoutExits a login shell.
popdRemoves entries from the directory stack.
printfDisplays text using formatted strings.
pushdAdds a directory to the directory stack.
pwdDisplays the pathname of the current working directory.
readReads one line of data from STDIN, and assigns it to a variable.
readonlyReads one line of data from STDIN, and assigns it to a variable that can’t be changed.
returnForces a function to exit with a value that can be retrieved by the calling script.
setSets and displays environment variable values and shell attributes.
shiftRotates positional parameters down one position.
shoptToggles the values of variables controlling optional shell behavior.
sourceReads and executes commands from a designated file in the current shell.
suspendSuspends the execution of the shell until a SIGCONT signal is received.
testReturns an exit status of 0 or 1 based on the specified condition.
timesDisplays the accumulated user and system shell time.
trapExecutes the specified command if the specified system signal is received.
typeDisplays how the specified words would be interpreted if used as a command.
typesetDeclares a variable or variable type.
ulimitSets a limit on the specific resource for system users.
umaskSets default permissions for newly created files and directories.
unaliasRemoves specified alias.
unsetRemoves the specified environment variable or shell attribute.
untilLoop that is very similar to the while-loop except that it executes until the test-command executes succesfully. As long as the test-command fails, the until-loop continues.
waitMake the shell wait for a job to finish.
whileWaits for the specified process to complete, and returns the exit status.

Overview Of Bash Symbols

Here we have gathered a collection of all arcane syntax along with a brief description. A bunch of these symbols are repeated from earlier but many are new - this is a good starting point if you are new to the language.

#used for comments
$used for parameters and variables. Has a bunch of edge cases.
()is used for running commands in a subshell.
$()is used for saving output of commands that are send to run in a subshell.
(( ))is used for arithmetic.
$(( ))is used for retrieving the output of arithmetic expressions, either for usage with a command or to save the output in a variable.
$[ ]deprecated integer expansion construct which is replaced by $(( )). Evaluates integers between the square brackets
[ ]is used for testing and is a built-in. Is useful in some cases for filename expansion and string manipulation.
[[ ]]is used for testing. This is the one you should use unless you can think of a reason not to.
<( )Used for process substitution and is similar to a pipe. Can be used whenever a command expects a file and you can use multiple at once.
{ }is used for expansion of sequences
${ }is used for variable interpolation and string manipulation.
|is a pipe which is used for chaining commands together.
<used for feeding input to commands from a file
>used for sending output to a file and erasing any previous content in that file.
||logical or
&&logical and
used for option prefixes
used for the long-option prefixes
&used to send a job to the background
<<WORD<<-WORDis used for heredocs
<<‘WORD'<<-‘WORD’is used for here strings
<<<is used to append output to a file.
>>single quotes are used to preserve the literal value
‘ ‘double quotes are used to preserve the literal value of all characters except $, ` ` and
” “backslash is used to escape otherwise interpreted symbols/characters which has a special meaning
\used for seperating the components of a filename
/similar to a NOP – a do nothing operation. It is a shell builtin with an exit status of true
:used to seperate commands intended to run sequentally.
;used for linking together arithmetic operations. All are evalutated but only the last is returned
,represents the current directory.
.represents parent directory.
..expands to home directory.
~is deprecated and should not be used. Read further in its respective section.
` `is deprecated and should not be used. Read further in its respective section.

Flow Control

Flow control structures in Bash are straight forward, albeit Bash is unforgiving if you get the syntax wrong.

View examples on how to use control flow in bash.

Ifif then fiTest a condition.
If-elseif then else fiTest a condition and use a fallback if the test fails.
If-elif-elseif then elif else fiProvides additional testing plus a fallback if all tests fail. You may skip the elif conditions or add as many in-between as you like. Similarly, you may skip the else fallback.
Forfor do doneIterate over a sequence, a list or anything as far as the imagination goes.
Whilewhile do doneWhile a condition is true – repeat until that condition is no longer true
Untiluntil do doneThe inverse of the while loop – as long as the test-command fails, the until-loop continues.
Selectselect in do donUsed for easy menu generation. Any statement within can be another select construct, thus enabling sub-menu creation.
Casecase ) ;; esacAlternative if-branching. Each case is an expression which matches a given pattern (i.e., a case).

We hope this cheat sheet has proved useful to you. The bash terminal is a powerful tool for automating tasks and managing settings. It is useful for everyone from system administrators, developers, and cyber security personnel to the average user who chooses Linux as their daily driver.

We encourage you to take a look at our Linux Command Line Cheat Sheet, Unix Commands Cheat Sheet, and Tmux Cheat Sheet to fully develop your knowledge base and make the most out of the command line.

Frequently Asked Questions

Level Up in Cyber Security: Join Our Membership Today!

vip cta image
vip cta details
  • Nathan House

    Nathan House is the founder and CEO of StationX. He has over 25 years of experience in cyber security, where he has advised some of the largest companies in the world. Nathan is the author of the popular "The Complete Cyber Security Course", which has been taken by over half a million students in 195 countries. He is the winner of the AI "Cyber Security Educator of the Year 2020" award and finalist for Influencer of the year 2022.

  • Alishia says:

    Bash is the most commonly used shell nowadays. This bash cheat sheet would be an added benefit while using the terminal.

  • David Frascone says:

    I like ctrl- which sends a SIGQUIT which generally causes the currently running program to quit and dump core.

  • Nick Chizhov says:

    In section String Comparison Operators in table, operators ” is the same comment = “is greater than ASCII alphabetical order”

  • Nick Chizhov says:

    Operator ‘less’ and ‘greater’

  • >