\documentclass[10pt,a4paper]{article} % Packages \usepackage{fancyhdr} % For header and footer \usepackage{multicol} % Allows multicols in tables \usepackage{tabularx} % Intelligent column widths \usepackage{tabulary} % Used in header and footer \usepackage{hhline} % Border under tables \usepackage{graphicx} % For images \usepackage{xcolor} % For hex colours %\usepackage[utf8x]{inputenc} % For unicode character support \usepackage[T1]{fontenc} % Without this we get weird character replacements \usepackage{colortbl} % For coloured tables \usepackage{setspace} % For line height \usepackage{lastpage} % Needed for total page number \usepackage{seqsplit} % Splits long words. %\usepackage{opensans} % Can't make this work so far. Shame. Would be lovely. \usepackage[normalem]{ulem} % For underlining links % Most of the following are not required for the majority % of cheat sheets but are needed for some symbol support. \usepackage{amsmath} % Symbols \usepackage{MnSymbol} % Symbols \usepackage{wasysym} % Symbols %\usepackage[english,german,french,spanish,italian]{babel} % Languages % Document Info \author{tanglisha} \pdfinfo{ /Title (bash.pdf) /Creator (Cheatography) /Author (tanglisha) /Subject (Bash Cheat Sheet) } % Lengths and widths \addtolength{\textwidth}{6cm} \addtolength{\textheight}{-1cm} \addtolength{\hoffset}{-3cm} \addtolength{\voffset}{-2cm} \setlength{\tabcolsep}{0.2cm} % Space between columns \setlength{\headsep}{-12pt} % Reduce space between header and content \setlength{\headheight}{85pt} % If less, LaTeX automatically increases it \renewcommand{\footrulewidth}{0pt} % Remove footer line \renewcommand{\headrulewidth}{0pt} % Remove header line \renewcommand{\seqinsert}{\ifmmode\allowbreak\else\-\fi} % Hyphens in seqsplit % This two commands together give roughly % the right line height in the tables \renewcommand{\arraystretch}{1.3} \onehalfspacing % Commands \newcommand{\SetRowColor}[1]{\noalign{\gdef\RowColorName{#1}}\rowcolor{\RowColorName}} % Shortcut for row colour \newcommand{\mymulticolumn}[3]{\multicolumn{#1}{>{\columncolor{\RowColorName}}#2}{#3}} % For coloured multi-cols \newcolumntype{x}[1]{>{\raggedright}p{#1}} % New column types for ragged-right paragraph columns \newcommand{\tn}{\tabularnewline} % Required as custom column type in use % Font and Colours \definecolor{HeadBackground}{HTML}{333333} \definecolor{FootBackground}{HTML}{666666} \definecolor{TextColor}{HTML}{333333} \definecolor{DarkBackground}{HTML}{1F1F1F} \definecolor{LightBackground}{HTML}{F8F8F8} \renewcommand{\familydefault}{\sfdefault} \color{TextColor} % Header and Footer \pagestyle{fancy} \fancyhead{} % Set header to blank \fancyfoot{} % Set footer to blank \fancyhead[L]{ \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{C} \SetRowColor{DarkBackground} \vspace{-7pt} {\parbox{\dimexpr\textwidth-2\fboxsep\relax}{\noindent \hspace*{-6pt}\includegraphics[width=5.8cm]{/web/www.cheatography.com/public/images/cheatography_logo.pdf}} } \end{tabulary} \columnbreak \begin{tabulary}{11cm}{L} \vspace{-2pt}\large{\bf{\textcolor{DarkBackground}{\textrm{Bash Cheat Sheet}}}} \\ \normalsize{by \textcolor{DarkBackground}{tanglisha} via \textcolor{DarkBackground}{\uline{cheatography.com/25502/cs/22925/}}} \end{tabulary} \end{multicols}} \fancyfoot[L]{ \footnotesize \noindent \begin{multicols}{3} \begin{tabulary}{5.8cm}{LL} \SetRowColor{FootBackground} \mymulticolumn{2}{p{5.377cm}}{\bf\textcolor{white}{Cheatographer}} \\ \vspace{-2pt}tanglisha \\ \uline{cheatography.com/tanglisha} \\ \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Cheat Sheet}} \\ \vspace{-2pt}Not Yet Published.\\ Updated 29th June, 2021.\\ Page {\thepage} of \pageref{LastPage}. \end{tabulary} \vfill \columnbreak \begin{tabulary}{5.8cm}{L} \SetRowColor{FootBackground} \mymulticolumn{1}{p{5.377cm}}{\bf\textcolor{white}{Sponsor}} \\ \SetRowColor{white} \vspace{-5pt} %\includegraphics[width=48px,height=48px]{dave.jpeg} Measure your website readability!\\ www.readability-score.com \end{tabulary} \end{multicols}} \begin{document} \raggedright \raggedcolumns % Set font size to small. Switch to any value % from this page to resize cheat sheet text: % www.emerson.emory.edu/services/latex/latex_169.html \footnotesize % Small font. \begin{multicols*}{3} \begin{tabularx}{5.377cm}{x{4.42953 cm} p{0.54747 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Moving Around the Command Line}} \tn % Row 0 \SetRowColor{LightBackground} Forward one word & \%f \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} Back one word & \%b \tn % Row Count 2 (+ 1) % Row 2 \SetRowColor{LightBackground} Beginning of line & \textasciicircum{}a \tn % Row Count 3 (+ 1) % Row 3 \SetRowColor{white} End of line & \textasciicircum{}e \tn % Row Count 4 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{4.4793 cm} p{0.4977 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Editing the Command Line}} \tn % Row 0 \SetRowColor{LightBackground} Delete to end of line & \textasciicircum{}k \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} Delete from beginning of line to here & \textasciicircum{}u \tn % Row Count 3 (+ 2) % Row 2 \SetRowColor{LightBackground} Delete one letter backwards until space & \textasciicircum{}w \tn % Row Count 5 (+ 2) % Row 3 \SetRowColor{white} Swap this and prev letter & \textasciicircum{}t \tn % Row Count 6 (+ 1) % Row 4 \SetRowColor{LightBackground} Swap this and prev word & \%t \tn % Row Count 7 (+ 1) % Row 5 \SetRowColor{white} Clear screen (Lower case L) & \textasciicircum{}l \tn % Row Count 8 (+ 1) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{3.9816 cm} x{0.9954 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Misc Command Line}} \tn % Row 0 \SetRowColor{LightBackground} Run command "cmd" in the background & cmd \& \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Suspend the current process & \textasciicircum{}z \tn % Row Count 3 (+ 1) % Row 2 \SetRowColor{LightBackground} ├-Bring that process back & fg \tn % Row Count 4 (+ 1) % Row 3 \SetRowColor{white} └-Continue that process but in the background & bg \tn % Row Count 6 (+ 2) % Row 4 \SetRowColor{LightBackground} Search prev commands (type and it'll auto complete) & \textasciicircum{}r \tn % Row Count 8 (+ 2) % Row 5 \SetRowColor{white} └-No, not this one, a different one & \textasciicircum{}r (again) \tn % Row Count 10 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{2.93643 cm} x{2.04057 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Directing input/output}} \tn % Row 0 \SetRowColor{LightBackground} Direct input & fileContent=\$(\textless{}filename.txt) \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Write all output to a file & ls -lah \textgreater{} filename.txt \tn % Row Count 4 (+ 2) % Row 2 \SetRowColor{LightBackground} Append output to a file & echo "hello" \textgreater{}\textgreater{} filename.txt \tn % Row Count 6 (+ 2) % Row 3 \SetRowColor{white} Redirect standard output to filename & ls -lah 1\textgreater{}filename \tn % Row Count 8 (+ 2) % Row 4 \SetRowColor{LightBackground} Redirect and append standard outpput to filename & ls -lah 1\textgreater{}\textgreater{} filename \tn % Row Count 11 (+ 3) % Row 5 \SetRowColor{white} Redirect stderr to filename & ls -lah 2\textgreater{}filename \tn % Row Count 13 (+ 2) % Row 6 \SetRowColor{LightBackground} Redirect and append stderr to filename & ls -lah 2\textgreater{}\textgreater{}filename \tn % Row Count 15 (+ 2) % Row 7 \SetRowColor{white} Redirect both stdout and stderr to filename & ls -lah \&\textgreater{}filename \tn % Row Count 17 (+ 2) % Row 8 \SetRowColor{LightBackground} Redirect stderr to stdout & command 2\textgreater{}\&1 \tn % Row Count 19 (+ 2) % Row 9 \SetRowColor{white} Redirect stdout to stdout & command \textgreater{}\&1 \tn % Row Count 21 (+ 2) % Row 10 \SetRowColor{LightBackground} Redirect stdout to stderr & command \textgreater{}\&2 \tn % Row Count 23 (+ 2) % Row 11 \SetRowColor{white} Send output from one command to input of another & one command | another \tn % Row Count 26 (+ 3) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{2.4885 cm} x{2.4885 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Misc}} \tn % Row 0 \SetRowColor{LightBackground} Inject .env into your bash session & export \$(cat .env | xargs) \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Prompt the user & read -sp "Prompt" varName \tn % Row Count 4 (+ 2) % Row 2 \SetRowColor{LightBackground} Read in command line options / parameters & \seqsplit{https://linuxconfig.org/how-to-use-getopts-to-parse-a-script-options} \tn % Row Count 8 (+ 4) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{2.38896 cm} x{2.58804 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Arrays}} \tn % Row 0 \SetRowColor{LightBackground} Create & a=("one" "two" "three" "four" "five" "six") \tn % Row Count 3 (+ 3) % Row 1 \SetRowColor{white} ├- & declare -a a \tn % Row Count 4 (+ 1) % Row 2 \SetRowColor{LightBackground} ├- & declare -a a=("one" "two" "three") \tn % Row Count 6 (+ 2) % Row 3 \SetRowColor{white} ├- & a{[}index{]}="one" \tn % Row Count 7 (+ 1) % Row 4 \SetRowColor{LightBackground} |-{}- & a=( \$(echo "\$\{space\_delim\_str\}") ) \tn % Row Count 9 (+ 2) % Row 5 \SetRowColor{white} └-Assign command output to an array & files=( \$(ls) ) \tn % Row Count 11 (+ 2) % Row 6 \SetRowColor{LightBackground} Add multiple items & a+=("seven" "eight" "nine") \tn % Row Count 13 (+ 2) % Row 7 \SetRowColor{white} Copy & b=( "\$\{a{[}@{]}\}" ) \tn % Row Count 14 (+ 1) % Row 8 \SetRowColor{LightBackground} Print & echo "\$\{a{[}@{]}\}" \tn % Row Count 15 (+ 1) % Row 9 \SetRowColor{white} Length/Number of elements & "\$\{\#a{[}@{]}\}" \tn % Row Count 17 (+ 2) % Row 10 \SetRowColor{LightBackground} Get an element (Zero indexed) & "\$\{a{[}3{]}\}" \tn % Row Count 19 (+ 2) % Row 11 \SetRowColor{white} Slice & "\$\{a{[}@{]}:2:4\}" \tn % Row Count 20 (+ 1) % Row 12 \SetRowColor{LightBackground} Search (works with regex) and Replace & "\$\{a{[}@{]}/one/zero\}" \tn % Row Count 22 (+ 2) % Row 13 \SetRowColor{white} Search and Remove & "\$\{a{[}@{]}/two/\}" \tn % Row Count 23 (+ 1) % Row 14 \SetRowColor{LightBackground} Delete an element - leaves a hole & unset "\$\{a{[}2{]}\}" \tn % Row Count 25 (+ 2) % Row 15 \SetRowColor{white} Delete an element - no hole & pos=3; a=("\$\{a{[}@{]}:0:\$pos\}" "\$\{a{[}@{]}:\$((\$pos + 1))\}") \tn % Row Count 28 (+ 3) % Row 16 \SetRowColor{LightBackground} Delete entire array & unset a \tn % Row Count 29 (+ 1) % Row 17 \SetRowColor{white} Concat & c=( "\$\{a{[}@{]}\}" "\$\{b{[}@{]}\}" ) \tn % Row Count 31 (+ 2) \end{tabularx} \par\addvspace{1.3em} \vfill \columnbreak \begin{tabularx}{5.377cm}{x{2.38896 cm} x{2.58804 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Arrays (cont)}} \tn % Row 18 \SetRowColor{LightBackground} Load file content into array & a=( \textbackslash{}`cat "filename.txt" \textbackslash{}`) \tn % Row Count 2 (+ 2) % Row 19 \SetRowColor{white} Loop through array & for item in "\$\{a{[}@{]}\}" ; do ... done \tn % Row Count 4 (+ 2) % Row 20 \SetRowColor{LightBackground} └-by index & for index in "\$\{!a{[}@{]}\}" ; do ... done \tn % Row Count 6 (+ 2) % Row 21 \SetRowColor{white} └-use a range instead & for num in \{8..45\} ; do ... done \tn % Row Count 8 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{Always include the double quotes when dealing with arrays. If you don't, there's a good chance something will break unexpectedly. \newline \newline If you try to take a slice from indexes that don't exist in the array, you'll either get what {\emph{is}} there, or nothing if you completely miss it. There will be no error.} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{1.24425 cm} x{3.73275 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Hashes / Associative Arrays}} \tn % Row 0 \SetRowColor{LightBackground} Create & declare -A a \tn % Row Count 1 (+ 1) % Row 1 \SetRowColor{white} └- & declare -A a=({[}"ONE"{]}="one" {[}"TWO"{]}="two" {[}"THREE"{]}="three") \tn % Row Count 3 (+ 2) % Row 2 \SetRowColor{LightBackground} Set a value & a{[}"KEY"{]}="value" \tn % Row Count 5 (+ 2) % Row 3 \SetRowColor{white} Print a value & echo a{[}key{]} \tn % Row Count 7 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{Requires Bash 4 or higher. Doesn't seem to work in OSX Catalina, even with the right version of Bash. An alternative that's less awful than the \textless{}4 bash way is to use two arrays with matching indexes. \newline \newline if {[} "\$\{BASH\_VERSINFO:-0\}" -lt 4 {]}; then ... fi \newline \newline Aside from creation, they work just like regular arrays. When you use a key, it doesn't} \tn \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{3.03597 cm} x{1.94103 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Parameter Expansion}} \tn % Row 0 \SetRowColor{LightBackground} If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted. & \$\{parameter:-word\} \tn % Row Count 5 (+ 5) % Row 1 \SetRowColor{white} If parameter is unset or null, the expansion of word is assigned to parameter. The value of parameter is then substituted. Positional parameters and special parameters may not be assigned to in this way. & \$\{parameter:=word\} \tn % Row Count 14 (+ 9) % Row 2 \SetRowColor{LightBackground} If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted. & \$\{parameter:?word\} \tn % Row Count 24 (+ 10) % Row 3 \SetRowColor{white} If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted. & \$\{parameter:+word\} \tn % Row Count 29 (+ 5) % Row 4 \SetRowColor{LightBackground} Substring & \$\{parameter:offset:length\} \tn % Row Count 31 (+ 2) \end{tabularx} \par\addvspace{1.3em} \vfill \columnbreak \begin{tabularx}{5.377cm}{x{3.03597 cm} x{1.94103 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Parameter Expansion (cont)}} \tn % Row 5 \SetRowColor{LightBackground} Last char in string & \$\{parameter:-1:1\} \tn % Row Count 2 (+ 2) % Row 6 \SetRowColor{white} Expands to the names of variables whose names begin with prefix, separated by the first character of the IFS special variable. When '@' is used and the expansion appears within double quotes, each variable name expands to a separate word. & \$\{!prefix*\} or \$\{!prefix@\} \tn % Row Count 13 (+ 11) % Row 7 \SetRowColor{LightBackground} If name is an array variable, expands to the list of array indices (keys) assigned in name. If name is not an array, expands to 0 if name is set and null otherwise. When '@' is used and the expansion appears within double quotes, each key expands to a separate word. & \$\{!name{[}@{]}\} or \$\{!name{[}*{]}\} \tn % Row Count 25 (+ 12) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{2.4885 cm} x{2.4885 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Brackets}} \tn % Row 0 \SetRowColor{LightBackground} Run commands in a subshell & ( ls -la ) \tn % Row Count 2 (+ 2) % Row 1 \SetRowColor{white} Create an array & x=( "a" "b" "c" ) \tn % Row Count 3 (+ 1) % Row 2 \SetRowColor{LightBackground} Split string on character (space) & IFS=' ' names=("mary joe bob") \tn % Row Count 5 (+ 2) % Row 3 \SetRowColor{white} Integer arithmetic (does not return result) & i=0; (( \$i += 1 )) \tn % Row Count 8 (+ 3) % Row 4 \SetRowColor{LightBackground} Interger arethemetic (returns result) & i=\$(( 1 + 1)) \tn % Row Count 10 (+ 2) % Row 5 \SetRowColor{white} Process substitution - pipe the stdout of multiple commands & comm \textless{}(ls -l) \textless{}(ls -al) \tn % Row Count 13 (+ 3) % Row 6 \SetRowColor{LightBackground} Turn subshell command result into string & echo "My name is \$( whoami )" \tn % Row Count 15 (+ 2) % Row 7 \SetRowColor{white} Truthiness check (Use for the -z -x -n type checks) & {[} -z \$x {]} \tn % Row Count 18 (+ 3) % Row 8 \SetRowColor{LightBackground} True/False testing & {[}{[} \$a \textasciitilde{}= /s/ {]}{]} \tn % Row Count 19 (+ 1) % Row 9 \SetRowColor{white} Expansion & mkdir something/\{sibling1,sibling2,sibling3\} \tn % Row Count 22 (+ 3) % Row 10 \SetRowColor{LightBackground} Range & \{0..5\} \{0..8..2\} \tn % Row Count 23 (+ 1) % Row 11 \SetRowColor{white} Command grouping & {[}{[} \$a \textasciitilde{}= /s/ {]}{]} \&\& \{ echo "hey!"; echo "newline" \} \tn % Row Count 26 (+ 3) % Row 12 \SetRowColor{LightBackground} Variables in a string & "Some string \$\{variable1:default value\}" \tn % Row Count 28 (+ 2) % Row 13 \SetRowColor{white} \mymulticolumn{2}{x{5.377cm}}{String manipulation} \tn % Row Count 29 (+ 1) % Row 14 \SetRowColor{LightBackground} ├-Remove from the front, matching the pattern */, non-greedy \# =\textgreater{} /example.com/wat & \seqsplit{url=https://example.com/wat} \$\{url\#*/\} \tn % Row Count 34 (+ 5) \end{tabularx} \par\addvspace{1.3em} \vfill \columnbreak \begin{tabularx}{5.377cm}{x{2.4885 cm} x{2.4885 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Brackets (cont)}} \tn % Row 15 \SetRowColor{LightBackground} ├-Remove from the front, matching the pattern */, greedy \# =\textgreater{} /wat & \seqsplit{url=https://example.com/wat} echo \$\{url\#\#*/\} \tn % Row Count 4 (+ 4) % Row 16 \SetRowColor{white} ├-Remove from the back, matching the pattern /*, non-greedy \# =\textgreater{} https://example.com & \seqsplit{url=https://example.com/wat} echo \$\{url\%/*\} \tn % Row Count 9 (+ 5) % Row 17 \SetRowColor{LightBackground} ├-Remove from the back, matching the pattern /*, greedy \# =\textgreater{} https://example.com & \seqsplit{url=https://example.com/wat} echo \$\{url\%\%/*\} \tn % Row Count 14 (+ 5) % Row 18 \SetRowColor{white} ├-Replace pattern =\textgreater{} ftp://example.com & \seqsplit{url=https://example.com} echo \$\{url/https/ftp\} \tn % Row Count 17 (+ 3) % Row 19 \SetRowColor{LightBackground} └-Global replace pattern =\textgreater{} https://XxamplX.com & \seqsplit{url=https://example.com} echo \$\{url//{[}e{]}/X\} \tn % Row Count 20 (+ 3) % Row 20 \SetRowColor{white} Multiline strings/heredocs & x=\textless{}\textless{}EOF ... many lines ... EOF \tn % Row Count 22 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} \begin{tabularx}{5.377cm}{x{2.78712 cm} x{2.18988 cm} } \SetRowColor{DarkBackground} \mymulticolumn{2}{x{5.377cm}}{\bf\textcolor{white}{Truth checks}} \tn % Row 0 \SetRowColor{LightBackground} True if variable is set or empty (No error if not set) & {[}{[} -z \$\{varName+x\} {]}{]} \tn % Row Count 3 (+ 3) % Row 1 \SetRowColor{white} True if variable is NOT set & {[}{[} -n \$varName {]}{]} \tn % Row Count 5 (+ 2) % Row 2 \SetRowColor{LightBackground} True if variable is set (Bash 4.5+) & {[}{[} -v \$varName {]}{]} \tn % Row Count 7 (+ 2) % Row 3 \SetRowColor{white} True if file exists & {[}{[} -f /file/path {]}{]} \tn % Row Count 9 (+ 2) % Row 4 \SetRowColor{LightBackground} True if directory exists & {[}{[} -d /directory/path {]}{]} \tn % Row Count 11 (+ 2) % Row 5 \SetRowColor{white} True if symbolic link exists & {[}{[} -L \seqsplit{/symbolic/link/path} {]}{]} \tn % Row Count 13 (+ 2) % Row 6 \SetRowColor{LightBackground} \mymulticolumn{2}{x{5.377cm}}{Files} \tn % Row Count 14 (+ 1) % Row 7 \SetRowColor{white} ├- -e & Exists \tn % Row Count 15 (+ 1) % Row 8 \SetRowColor{LightBackground} ├- -d & Directory \tn % Row Count 16 (+ 1) % Row 9 \SetRowColor{white} ├- -f & Non-directory file \tn % Row Count 18 (+ 2) % Row 10 \SetRowColor{LightBackground} ├- -r & Readable file \tn % Row Count 19 (+ 1) % Row 11 \SetRowColor{white} ├- -w & Writeable file \tn % Row Count 20 (+ 1) % Row 12 \SetRowColor{LightBackground} ├- -x & Executable file \tn % Row Count 21 (+ 1) % Row 13 \SetRowColor{white} ├- -L & Symbolic link \tn % Row Count 22 (+ 1) % Row 14 \SetRowColor{LightBackground} ├- -S & Socket \tn % Row Count 23 (+ 1) % Row 15 \SetRowColor{white} └- -s & File exists and has nonzero size \tn % Row Count 25 (+ 2) \hhline{>{\arrayrulecolor{DarkBackground}}--} \end{tabularx} \par\addvspace{1.3em} % That's all folks \end{multicols*} \end{document}