% $Id: tools_basic.tex,v 1.1 2003/11/27 02:44:21 nicku Exp nicku $ \chapter{Basic Tools} \label{cha:basic-tools} {\mns \subsection{Objectives} \label{sec:basic-linux-unix-tools-objectives} At the end of this section, you will be able to: \begin{itemize} \item Use the most frequently used Linux tools to: \begin{itemize} \item Find files \item Get information about commands \item View file contents \item Get information about files \item Operate on file contents \item Do simple text manipulation \item Schedule jobs \end{itemize} \item Combine tools to solve problems \item Understand and use the Linux printing subsystem \end{itemize} \section{Introduction} \label{sec:basic-linux-unix-tools-intro} The basic Linux command-line utilities dealt with here, are: \renewcommand*{\bottomfraction}{.6} % default is 0.3 \renewcommand*{\topfraction}{.9} % default is 0.7 \renewcommand*{\textfraction}{0.05} % default is 0.2 \begin{table}[h]% \begin{center}% {\myss \medskip %%\setlength{\extrarowheight}{1pt} %% \begin{tabular}[t]{|l|l|} \hline %% Finding files & {\pgn find} \\ %% & {\pgn locate} \\ \hline %% Getting info about commands & {\pgn man} \\ \hline %% Viewing file contents & {\pgn cat} \\ %% & {\pgn less} \\ %% & {\pgn head}/{\pgn tail} \\ \hline %% Getting information about a file & {\pgn ls} \\ %% & {\pgn file} \\ %% & {\pgn wc} \\ %% & {\pgn diff} \\ %% & {\pgn cmp} \\ \hline %% Operating on file contents & {\pgn grep} \\ %% & {\pgn sort} \\ %% & {\pgn uniq} \\ %% & {\pgn split}/{\pgn csplit} \\ %% & {\pgn cut} \\ %% & {\pgn paste} \\ %% & {\pgn tar} \\ %% & {\pgn gzip}/{\pgn bzip2} \\ \hline %% Simple text manipulation & {\pgn tr} \\ %% & {\pgn expr} \\ \hline %% Scheduling jobs & {\pgn at} \\ %% & {\pgn crontab} \\ \hline %%\end{tabular} \setlength{\extrarowheight}{0pt}% \begin{tabular}[t]{l>{\pgn}l} \toprule Finding files: & {\pgn find} \\ & {\pgn locate} \\ \midrule Getting info about commands: & {\pgn man} \\ \midrule Viewing file contents: & {\pgn cat} \\ & {\pgn less} \\ & {\pgn head}/{\pgn tail} \\ \midrule Getting information about a file: & {\pgn ls} \\ & {\pgn file} \\ & {\pgn wc} \\ & {\pgn diff} \\ & {\pgn cmp} \\ \midrule Operating on file contents: & {\pgn grep} \\ & {\pgn sort} \\ & {\pgn uniq} \\ & {\pgn split}/{\pgn csplit} \\ & {\pgn cut} \\ & {\pgn paste} \\ & {\pgn tar} \\ & {\pgn gzip}/{\pgn bzip2} \\ \midrule Simple text manipulation: & {\pgn tr} \\ & {\pgn expr} \\ \midrule Scheduling jobs: & {\pgn at} \\ & {\pgn crontab} \\ \bottomrule \end{tabular} } \caption{Basic Linux utilities} \label{tab:basic-linux-utilities} \end{center} \end{table} \section{Using Tools} \label{sec:basic-linux-unix-tools-using-tools} \begin{itemize} \item Typical Linux systems contain over 1000 command-line tools \item Tools are combined (via pipes and redirection) to solve specific problems \item Most tools have a standard syntax: \begin{quote} {\cmdn \$ command [{\usb options}] [{\usb files ... }]} \end{quote} \item Some arguments must be quoted \item Standard input often read if no filename given \item Most tools can take several filename arguments \item Desktop/windowing environments may provide graphical wrappers to some tools \item Serious Linux administrators and users know the key command-lines well \item The terms `command' and `tool' are used interchangeably here \end{itemize} \section{The On-Line Manual ({\pgn man})} \label{sec:basic-linux-unix-tools-basic-man} \begin{itemize} \item Most commands have an associated man page \item Accessed by typing: {\cmdn \$ man {\usb command}[s]} \item Brings up a page of information usually detailing: \begin{itemize} \item command name, section number, description \item syntax \item options \item version information \item location of configuration files \item other related commands \item examples of usage \item known bugs (if any \ldots) \end{itemize} \end{itemize} \section{Finding Files the Long Way ({\pgn find})} \label{sec:basic-linux-unix-tools-find} %IMPROVEME: This foil on find needs to be split up into two or more clearer foils, it's too icky at the moment (LW) \begin{itemize} \item {\pgn find} searches the filesystem in real time; \begin{itemize} \item Makes disks work hard \end{itemize} \item Can find files by name, type, size, dates, e.g \begin{itemize} \item To find all files ending with {\fn .jpg} under the current directory:\\ {\cmdn find . -name "*.jpg"} \item To find all filenames ending in {\fn .jpg} {\em and} modified in the last 8 days below {\fn /etc}\\ {\cmdn find /etc -name "*.jpg" -mtime -8} \end{itemize} \item Tests can be combined with {\cmdn -o} and negated with {\kbk !}, for example: \begin{itemize} \item To find all filenames {\em not} ending in {\fn .jpg} {\em or} files which were modified in the last 8 days under {\fn /etc}\\ {\cmdn find /etc \bs! -name "*.jpg" -o -mtime -8} \end{itemize} \item Can execute commands on the files it finds. The name of the file found is placed in \{\}~\footnote{This is not a resource friendly way of doing things. {\cmdn xargs} may be better} \begin{verbatim} find . -name "*.gif" -exec ls -l {} \; \end{verbatim} \end{itemize} \providecommand*{\bsn}{\texttt{\char '134}} \section{Find examples} \label{sec:find-examples} \begin{itemize} \item First, an example which is wrong: \begin{alltt} $ \textbf{find /usr/bin/c*} # WRONG! \end{alltt}%$ This is \emph{wrong} because the shell expands the \texttt{c*} to all the files before \texttt{find} even begins. \item Here is the right way to find files beginning with ``\texttt{c}'' under the \texttt{/usr/bin} directory: \begin{alltt} $ \textbf{find /usr/bin -name c\bs*} \end{alltt}%$ Note that we need to quote the ``\texttt{*}'', because we want \texttt{find} to have the star, we don't want the shell to turn it into a list of files starting with ``\texttt{c}'' in the current directory. \item Find man pages that are bigger than 10\,k: \begin{alltt} $ \textbf{find /usr/share/man -size +10k} \end{alltt}%$ \item Find man pages that are bigger than 10\,k but smaller than 15\,k: \begin{alltt} $ \textbf{find /usr/share/man -size +10k -size -15k} \end{alltt}%$ \item Find man pages that are smaller than 10\,k OR bigger than 15\,k: \begin{alltt} $ \textbf{find /usr/share/man -size -10k -o -size +15k} \end{alltt}%$ We use the logical OR operator ``\texttt{-o}'' \item Find man pages that are smaller than 10\,k but bigger than 15\,k and which are ordinary files (not directories or symbolic links): \begin{alltt} \myss$ \textbf{find /usr/share/man -type f \bs( -size -10k -o -size +15k \bsn)} \end{alltt}%$ We need to use parentheses to group the OR operation first, otherwise it will test for files that are smaller than 10\,k and which are normal files, OR for \emph{any} files that are bigger than 15\,k. The parentheses must be quoted or the shell will try to start a shubshell. \end{itemize} \section{Locate Files ({\cmdn locate})} \label{sec:basic-linux-unix-tools-locate} \begin{itemize} \item {\cmdn locate} searches a periodically-updated database of the filesystem(s) \begin{itemize} \item Not available on all systems \item Very fast, but DB needs regular updating, e.g. \begin{alltt} $ \textbf{updatedb} \end{alltt}%$ \item Usually updated nightly automatically \end{itemize} \item Won't be there on a fresh install \item Won't show files created since last database update \item Given the command `{\cmdn locate {\usb string}}', {\pgn locate} will show all files containing {\usb string} in their full pathname, e.g. \ \begin{alltt} $ \textbf{locate logrotate} /usr/man/man8/logrotate.8 /usr/sbin/logrotate /etc/logrotate.d /etc/logrotate.d/cron /etc/logrotate.d/syslog /etc/logrotate.d/linuxconf /etc/logrotate.d/ftpd /etc/logrotate.d/samba /etc/cron.daily/logrotate /etc/logrotate.conf \end{alltt}%$ \end{itemize} \section{View and Concatenate Files ({\pgn cat})} \label{sec:basic-linux-unix-tools-cat} \begin{itemize} \item Displays and/or joins (con{}\framebox{cat}enates) files \item Sends the content of named file(s) to standard output \item If no filename is given, it reads from standard input and writes to standard output \item Given more than one filename, it displays each file's contents sequentially, i.e, joins them \item Example: \begin{alltt} $ \textbf{cat file1 file2 file3 > all_files} \end{alltt}%$ \end{itemize} \section{View Large Files \& Output ({\pgn less})} \label{sec:basic-linux-unix-tools-less-more} \begin{itemize} \item {\pgn less} displays the contents of file(s) in a controlled way on stdout \begin{itemize} \item Usually, one page at a time \item Like UNIX/DOS command {\pgn more}, on steroids \end{itemize} \item You can search for patterns in the file \item It allows you to move quickly to {\em any} point (backwards or forwards) \item Similar usage to {\pgn more}, {\pgn vi}, and {\pgn lynx}: \begin{table}[htbp] \begin{center} {\myss \begin{tabular}[t]{|>{\PBS\rr}p{210pt}|>{\PBS\rr}p{220pt}|} \hline Action & Keystokes \\ \hline \hline Top of page & {\kbk g < ESC-<} \\ Bottom of page & {\kbk G > ESC->} \\ Forward one screen & {\kbk f \^{}F \^{}V SPACE} \\ Backward one screen & {\kbk b \^{}B ESC-v} \\ Up one line & {\kbk y \^{}Y k \^{}K \^{}P} \\ Down one line & {\kbk e \^{}E j \^{}N RETURN} \\ {\usb pattern} Search forward & {\kbk /{\usb pattern}} \\ {\usb pattern} Search backward & {\kbk ?{\usb pattern}} \\ Repeat {\usb pattern} Search forward & {\kbk n} \\ Repeat {\usb pattern} Search backward & {\kbk N} \\ Move to {\usb n}th line & {\kbk {\usb n}g} \\ !command & Execute the shell command with \${}SHELL \\ |Xcommand & Pipe file between current pos \&\ mark X to shell command \\ v & Edit the current file with \${}VISUAL or \${}EDITOR \\ \hline \end{tabular} \caption{Commands within {\pgn less}} \label{tab:commands-in-less} } \end{center} \end{table} \end{itemize} \section{Viewing Parts of Files ({\pgn head} and {\pgn tail})} \label{sec:basic-linux-unix-tools-head-tail} \begin{itemize} \item {\pgn head} displays the first few lines of a file \item {\pgn tail} displays the last few lines of a file \item You can specify how many lines are displayed \begin{itemize} \item To display only the first 4 lines: {\sco \$ head -4 {\usb filename}} \end{itemize} \item {\cmdn tail -f} often used to monitor growing files, e.g., \begin{alltt} $ \textbf{sudo tail -f /var/log/messages} \end{alltt}%$ \end{itemize} \section{Listing File Information ({\pgn ls})} \label{sec:basic-linux-unix-tools-ls} \begin{itemize} \item Without any options, {\pgn ls} lists files in the current directory \item By default all files starting with {\kbk .} (dot) aren't shown \item The most common options to {\pgn ls} include: \vspace{5pt} \begin{table}[htbp] \begin{center} {\myss \begin{tabular}[t]{|l|>{\PBS\rr}p{333pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -l} & {\em Long} (detailed) listing of file info, including: size, ownership, permissions and type\\ {\cmdn -a} & Show {\em all} files, including hidden ones \\ {\cmdn -F} & Highlight directories and executables with {\sco /} and {\sco @} respectively \\ {\cmdn -R} & {\em Recursively} list subdirectories \\ {\cmdn -t} & Sort list by last modification {\em time} \\ {\cmdn -u} & Sort list by last access time (with {\cmdn -t}) \\ {\cmdn -X} & Sort list by file e{\em X}tension \\ {\cmdn -r} & Reverse order of listing \\ {\cmdn -d} & Show directory information not directory contents \\ \hline \end{tabular} } \caption{Common options to {\pgn ls}} \label{tab:common-options-t0-less} \end{center} \end{table} \item For example: \begin{verbatim} $ ls -lrt \end{verbatim}%$ show files in reverse order based on their modification time \end{itemize} \section{File Classification ({\pgn file})} \label{sec:basic-linux-unix-tools-file} \begin{itemize} \item {\pgn file} displays the type of data contained in named file(s) \item It works by: \begin{enumerate} \item opening each named file \item reading the beginning of the file \item comparing what it finds there with the patterns in the ``magic'' file {\fn /usr/share/magic} \item reports the matching file type found in the magic file. \end{enumerate} \item Results not always correct \item Classifications include: executable, archive, \\C program, ASCII text, JPEG image \ldots \item You can use it like this: \begin{alltt} $ \textbf{file /usr/bin/*} \end{alltt}%$ %% {\myss %% {\cmdn file [-vbczL] [-f {\usb filename}] [-m {\usb magicfiles}] file\ldots} %% } \end{itemize} \section{Count Words, Lines, Characters ({\pgn wc})} \label{sec:basic-linux-unix-tools-wc} \begin{itemize} \item {\pgn wc} displays the number of lines, words,\footnote{A `word', in this context, is a character string surrounded by SPACEs, TABs, NEWLINEs, or a combination of them.} and characters in a file \vspace{10pt} \begin{table}[htbp] \begin{center} {\mns \begin{tabular}[t]{|l|p{305pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -l} & Only displays the number of lines \\ {\cmdn -w} & Only displays the number of `words' \\ {\cmdn -c} & Only displays the number of characters \\ \hline \end{tabular} } \caption{Options to the {\pgn wc} command} \label{tab:wc-options} \end{center} \end{table} \end{itemize} \section{Differences Between Files ({\pgn diff})} \label{sec:basic-linux-unix-tools-diff} \begin{itemize} \item {\pgn diff} displays the difference between two {\em text} files, line-by-line \item Output from {\pgn diff} can be confusing \item For example, given the files {\usb text1} and {\usb text2}: \begin{quote} {\bf text1:} \\ This is a temprary test \\ to check the diff \\ utility \end{quote} \begin{quote} {\bf text2:} \\ This is a temporary test \\ to check the diff \\ utility. \end{quote} \vspace{10pt} \begin{enumerate} \item A simple line-by-line comparison: \begin{quote} \begin{verbatim} $ diff text1 text2 1c1 < This is a temprary test --- > This is a temporary test 3c3 < utility --- > utility. \end{verbatim} %$ \end{quote} \pagebreak \item Using the context output format ({\cmdn -c}): \begin{verbatim} $ diff -c text1 text2 *** text1 Mon Apr 19 14:46:25 1999 --- text2 Mon Apr 19 14:46:05 1999 *************** *** 1,3 **** ! This is a temprary test to check the diff ! utility --- 1,3 ---- ! This is a temporary test to check the diff ! utility. \end{verbatim} %$ \item Using the unified output format ({\cmdn -u}): (Most common) \begin{verbatim} $ diff -u text1 text2 --- text1 Mon Apr 19 14:46:25 1999 +++ text2 Mon Apr 19 14:46:05 1999 @@ -1,3 +1,3 @@ -This is a temprary test +This is a temporary test to check the diff -utility +utility. \end{verbatim}%$ \end{enumerate} \end{itemize} \section{Compare Binary Files ({\pgn cmp})} \label{sec:basic-linux-unix-tools-cmp} \begin{itemize} \item Displays differences between 2 {\em binary} files \item Locates the byte and line number of the first difference \item Can show {\em all} differences if required, e.g. {\cmdn cmp -l {\usb file1} {\usb file2}} \item {\cmdn cmp -s} suppresses output and returns exit status \begin{itemize} \item {\sco 0} if the files are identical \item {\sco 1} if the files differ \item {\sco 2} if an error has occurred \end{itemize} \item Often used in shell scripts \end{itemize} \section{Regular Expression Searches ({\pgn grep})} \label{sec:basic-linux-unix-tools-grep} \begin{itemize} \item Search for regular expressions in file(s) \begin{quote} {\myss i.e ``\framebox{g}lobally find \framebox{r}egular \framebox{e}xpressions and \framebox{p}rint''} \end{quote} \item Usage:\\ {\cmdn grep [options] search-pattern files} \item Reads standard input if no filenames are given \item Matching lines are printed to standard output \item Popular options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\myss \begin{tabular}[t]{|l|>{\PBS\rr}p{313pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -i} & Ignore case \\ {\cmdn -l} & List only filenames containing the expression \\ {\cmdn -v} & Reverse sense of test, i.e. find non-matching lines \\ {\cmdn -w} & Word search, i.e. match whole word \\ {\cmdn -E} & Extended regular expression search (more complex patterns), {\pgn egrep} similar \\ {\cmdn -F} & Fixed string pattern search, same as {\pgn fgrep} \\ \hline \end{tabular} } \caption{Popular {\pgn grep} options} \label{tab:popular-grep-options} \end{center} \end{table} \end{itemize} \section{{\pgn grep} examples} \label{sec:basic-linux-unix-tools-grep-examples} \begin{itemize} \item Search for a user in the password file {\myfs \begin{verbatim} $ grep lee /etc/passwd lee:x:500:500:Lee Willis:/home/lee:/bin/bash \end{verbatim}} %$ \item Search for events in a log\footnote{You need to be logged in as root to see inside /var/log/secure.} {\myfs \begin{verbatim} # grep connect /var/log/secure Mar 8 14:42:53 rafters in.telnetd[579]: connect from 192.168.0.129 Mar 13 10:27:40 rafters in.telnetd[724]: connect from 192.168.0.139 Mar 13 16:54:24 rafters in.telnetd[2135]: connect from 192.168.0.139 Mar 20 10:54:38 rafters in.telnetd[816]: connect from 127.0.0.1 \end{verbatim}} \item Search for a function in source code {\myfs \begin{verbatim} $ grep "int main" *.cpp checkrefint.cpp:int mainbit(); checkrefint.cpp:int mainbit(){ do_maint.cpp:int maint(Form &Myform){ expire.cpp:int main(void){ maint_login.cpp:int maint_login(Form &) { \end{verbatim}} %$ \end{itemize} \section{Sort and Merge Files ({\pgn sort})} \label{sec:basic-linux-unix-tools-sort} \begin{itemize} \item {\pgn sort} and/or merge files \item Acts as a filter without file arguments \item Sorts entire lines lexically, by default \item Alternative sort orders: \\[12pt] \begin{table}[htbp] \begin{center} {\mns \begin{tabular}[t]{|l|p{313pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -n} & Numerical order \\ {\cmdn -r} & Reverse order \\ \hline \end{tabular} } \caption{Alternative {\pgn sort} orders} \label{tab:alternative-sort-orders} \end{center} \end{table} \item Other popular options: \\[12pt] \begin{table}[htbp] \begin{center} {\myss \begin{tabular}{|l|>{\PBS\rr}p{248pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -b} & Blanks (TAB, SPACE) ignored \\ {\cmdn -f} & Fold lowercase to upper before sorting \\ {\cmdn -i} & Ignore non-printable characters \\ {\cmdn -m} & Merge files, without checking if sorted \\ {\cmdn -t{\usb x}} & Set field delimiter in file as {\usb x} \\ {\cmdn -u} & Unique, outputs repeat lines once only \\ {\cmdn -k {\usb POS1[,POS2]}} & Specify a field in each line as a sorting key, starting at {\usb POS1} and ending at {\usb POS2} (or NEWLINE). Fields and character positions are numbered starting at 1 \\ \hline \end{tabular} } \caption{Popular {\pgn sort} options} \label{tab:popular-sort-options} \end{center} \end{table} \end{itemize} \section{{\pgn sort} Examples} \label{sec:basic-linux-unix-tools-sort-examples} Consider {\fn /etc/passwd} which typically contains lines in the following format: {\Large {\sco username:password:UID:GID:Realname:Homedirectory:shell}} \begin{itemize} \item To sort by username:\\ {\sco \$ sort -t: -f -k1,1 /etc/passwd} \item To sort numerically by user ID:\\ {\sco \$ sort -t: -n -k3,3 /etc/passwd} \item To sort by real name within group ID:\\ {\sco \$ sort -t: -k4,4n -k5,5f /etc/passwd} \end{itemize} \vspace{16pt} % This picture does not help at all. %\begin{center} % \includegraphics{../images/basic_tools_sorting}\\[16pt] %{\cmdn sort -r} %\end{center} \section{Display Unique Lines ({\pgn uniq})} \label{sec:basic-linux-unix-tools-uniq} \begin{itemize} \item Removes all but one of successively repeated lines \item Acts on standard input, often piped from {\pgn sort} \item Most popular options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\myss \begin{tabular}[t]{|l|>{\PBS\rr}p{313pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -c} & Put a count of how many lines were duplicate in front of each line \\ {\cmdn -d} & Duplicated lines only are displayed \\ {\cmdn -u} & Unique lines only are displayed \\ {\cmdn -{\usb n}} & Ignore the first {\usb n} fields \\ {\cmdn +{\usb n}} & Ignore the first {\usb n} characters \\ {\cmdn -w} & Specify the number of chars to compare \\ \hline \end{tabular} } \caption{Popular {\pgn uniq} options} \label{tab:popular-uniq-options} \end{center} \end{table} \item Example:\\[16pt] \includegraphics{../images/basic_tools_sorting_and_uniq}\\[16pt] \end{itemize} \section{Split Files ({\pgn split})} \label{sec:basic-linux-unix-tools-split} \begin{itemize} \item Split a file into pieces \item Outputs sections to new files or standard output \item Creates files named {\uin prefixaa}, {\uin prefixab}, {\uin prefixac} \ldots \item Main {\pgn split} options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\myss \begin{tabular}[t]{|l|>{\PBS\rr}p{313pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -l{\usb n}} & Put {\usb n} lines of the input file into each output file \\ {\cmdn -b{\usb n}} & Put {\usb n} bytes of the input file into each output file \\ {\cmdn -C{\usb n}} & Put as many complete lines of the input file as is possible into the output file, up to {\usb n} bytes \\ \hline \end{tabular} } \caption{Main {\pgn split} options} \label{tab:popular-split-options} \end{center} \end{table} \section{Splitting Files by Context ({\pgn csplit})} \label{sec:basic-linux-unix-tools-split-files-by-context} \item Splits file into sections determined by context (patterns or regular extressions) \item Syntax: {\myfs \mbox{\sco csplit [-f prefix] [-b suffix] [-n digits] {\usb filename} pattern...}} \item Main {\pgn csplit} arguments: \vspace{10pt} \begin{table}[htbp] \begin{center} {\myss \begin{tabular}[t]{|l|>{\PBS\rr}p{257pt}|} \hline Argument & Instruction \\ \hline \hline {\cmdn {\usb /regexp/[offset]}} & Split the file at occurrence of {\usb regexp}. The line after the optional offset (`+' or `-' followed by a number) begins next bit of input \\ {\cmdn {\usb \{repeat-count\}}} & Repeat the previous pattern split {\usb n} times. Substitute an asterisk for {\usb n} to repeat until the input is exausted \\ {\cmdn -f{\usb string}} & Use {\usb string} as prefix of output filename \\ {\cmdn -b{\usb string}} & Use {\usb string} as suffix of output filename \\ {\cmdn -n{\usb n}} & Use output filenames {\usb n} digits long \\ \hline \end{tabular} } \caption{Main {\pgn csplit} arguments} \label{tab:main-csplit-arguments} \end{center} \end{table} \end{itemize} \section{Dividing files into columns: {\cmdn cut}} \label{sec:cut} \begin{itemize} \item Often need to separate one or more columns from input. \begin{itemize} \item {\cmdn cut} provides a simple way; \item {\cmdn awk} provides another way (more flexible; see later). \item Use {\cmdn paste} to join columns together \end{itemize} \item Syntax: \texttt{cut} \meta{options} [\meta{files}] \item Cuts out the selected columns or fields from one or more \meta{files}. \item Can specify a range of values with a hyphen, and use a comma to separate values, e.g., \texttt{1-10,15,20,} or \texttt{50-} \item Options: \begin{description} \item[\texttt{-b}, \texttt{--bytes} \meta{list}] Specify \meta{list} of positions; only bytes in those positions will be printed. \item[\texttt{-c}, \texttt{--characters} \meta{list}] Cut the column positions given in \meta{list} \item[\texttt{-d}, \texttt{--delimiter} \meta{c}] Use \texttt{-f} to specify field delimiter as character \meta{c} (default is tab); special characters must be quoted. \item[\texttt{-f}, \texttt{--fields} \meta{list}] Cut the fields given in \meta{list} \end{description} \item Examples: \begin{itemize} \item Extract usernames and real names from \texttt{/etc/passwd}: \begin{verbatim} cut -d: -f1,5 /etc/passwd \end{verbatim} \item Find out who is logged in, but only login names: \begin{verbatim} who | cut -d" " -f1 \end{verbatim} \item Cut characters from the fourth column of \texttt{file} and paste them back as the first column in the same file: \begin{verbatim} cut -c4 file | paste - file \end{verbatim} \end{itemize} \end{itemize} \section{Compression Utilities: {\pgn bzip2} and {\pgn gzip}} \label{sec:basic-linux-unix-tools-gzip} \begin{itemize} \item Linux has many compression utilities; {\pgn bzip2} and {\pgn gzip} dominate thanks to integration with {\pgn tar}, and excellent compression \item Takes files or standard input and compress them to file(s) or standard output \item Uses {\kwd lossless compression}, so safe on any file \item Key {\pgn bzip2} and {\pgn gzip} options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\myss \begin{tabular}{|l|>{\PBS\rr}p{295pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -r} & Recursive compression of subdirectories \\ {\cmdn -d} & Decompress (same as {\cmdn gunzip}) \\ {\cmdn -{\usb [1-9]}} & Fast or best compression, where 1 is fastest and 9 is most intense compression\\ \hline \end{tabular} } \caption{Key {\pgn bzip2} and {\pgn gzip} options} \label{tab:key-gzip-options} \end{center} \end{table} \item {\pgn bzip2} has significantly better compression ratios and is now widely used for distributing software. \item A set of files put into an archive with {\pgn tar} and {\pgn bzip2} gives \emph{much} better compression than can be achieved in zip files or rar archives. \end{itemize} \section{Store and Retrieve Archives ({\pgn tar})} \label{sec:basic-linux-unix-tools-tar} \begin{itemize} \item Originally designed to make tape archives \item Takes a group of files and creates one big file containing their contents {\em and} details \item Widely used for: \begin{itemize} \item Compression with {\pgn gzip} or {\pgn bzip2}~\footnote{The {\cmdn gzip} or {\cmdn bzip2} compression options are not available on all UNIX versions of {\pgn tar}.} \item Maintaining Linux file details (permissions, dates, ownership etc) on other filesystems \item Bundling file trees for distribution (called a \emph{tarball}) \end{itemize} \item Key {\usb tar} options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\myss \begin{tabular}{|l>{\PBS\rr}p{313pt}|} \hline Flag & Option \\ \hline \hline {\cmdn -t} & List files in an archive \\ {\cmdn -x} & Extract the contents from an archive \\ {\cmdn -c} & Create a new archive \\ {\cmdn -r} & Append files to an existing archive \\ \hline \hline {\cmdn -v} & Verbose: list file names, tell more of what's happening\\ {\cmdn -j} & Create/Open bzip2 compressed {\pgn tar} file(s) \\ {\cmdn -z} & Create/Open gzip compressed {\pgn tar} file(s) \\ {\cmdn -f} & Filename of the file or device to hold the archive \\ {\cmdn -p} & preserve permissions when extracting files \\ \hline \end{tabular} } \caption{Key {\pgn tar} options} \label{tab:key-tar-options} \end{center} \end{table} \vspace{-10pt} \item To create a {\pgn gzip} compressed archive of {\fn /etc}: \begin{verbatim} $ tar -cvzf /home/username/filename.tar.gz /etc \end{verbatim} %$ \item To extract the files into the current directory: \begin{verbatim} $ tar -xvzf filename.tar.bz2 \end{verbatim}%$ \item To create a {\pgn bzip2} compressed archive of {\fn /etc}: \begin{verbatim} $ tar -cvjf /home/username/filename.tar.gz /etc \end{verbatim}%$ \item To extract the files into the current directory: \begin{verbatim} $ tar -xvjf filename.tar.bz2 \end{verbatim}%$ \end{itemize} \section{Translating Characters ({\pgn tr})} \label{sec:basic-linux-unix-tools-tr} \begin{itemize} \item Translate characters in standard input into different characters in output \item Syntax: {\cmdn tr [{\uin options}] [{\usb string1} [{\usb string2}]]} \item Characters in {\usb string1} are replaced by the corresponding character in {\usb string2} \begin{verbatim} $ tr `abc` `123` abcdad 123d1d \end{verbatim} %$ \item Character position in both strings matters \item Both strings should be the same length~\footnote{If string1 is shorter than string2, the extra characters at the end of string2 are ignored. If string1 is longer, GNU {\pgn tr} follows BSD in padding string2 to the length of string1, by repeating the last character. With the {\cmdn -t} option it follows AT\&T by truncating string1 to the length of string2.} \end{itemize} \section{Examples of {\pgn tr} Usage} \label{sec:basic-linux-unix-tools-egs-tr} \begin{itemize} \item To replace all vowels in the input with spaces \begin{alltt} $ \textbf{tr 'aeiou' ' '} \end{alltt} %$ \item Using character ranges to translate all lower case letters into their upper case equivalents \begin{alltt} $ \textbf{tr 'a-z' 'A-Z'} \end{alltt} %$ \item Using the asterisk {\kbk *} to replace all 10 digits with the same letter `n'. In other words, \texttt{[n*10]} is the same as \texttt{'nnnnnnnnnn'} \begin{alltt} $ \textbf{tr '0-9' '[n*10]'} \end{alltt} %$ \item Use the {\cmdn -c} option (complement) to replace all characters in {\usb string1} which {\em don't} belong in a range \begin{alltt} $ \textbf{tr -cs 'a-zA-Z0-9' '[\bs{}n*]'} \end{alltt} %$ N.B. This puts every word on a line by itself, by converting all non-alphanumeric characters to newlines, then `squeezing' repeated newlines (with {\cmdn -s}) into a single newline. The pattern \texttt{[\bs{}n*]} in the second set means repeat the newline \texttt{\bs{}n} as many times as there are characters in the first set. See \texttt{man~tr}. \end{itemize} \section{Execute programs at specified times ({\pgn at})} \label{sec:at-batch} \begin{itemize} \item {\pgn at} executes a shell script at a specified time \item Syntax: {\cmdn \$ at [{\usb options}] {\usb time} [{\usb date}] +{\usb increment} } \item \verb|stdin| is scanned for commands to execute, e.g. {\myss \begin{verbatim} at 2300 at> fetchmail +D \end{verbatim} } \item Some more examples of how to specify time and date: {\myss \begin{verbatim} at 11pm at 1am at 5am tomorrow at 08:00 Sep 12 at now at now + 4 hours at now + 1 day at now + 2 months at now + 3 years at 5:30pm Thursday at teatime \end{verbatim} } \item Commands are executed in the current environment at the given time \item \verb|stdout| and \verb|stderr| are sent as mail \end{itemize} \section{Options and commands related to {\pgn at}} \label{sec:at-options} \begin{itemize} \item {\pgn at} belongs to a family of utilities for managing time-specified commands {\myss \begin{tabular}[t]{|>{\PBS\rr}p{90pt}|>{\PBS\rr}p{243pt}|} \hline Command & Purpose \\ \hline \hline {\pgn atq} & Display list of queued {\pgn at} commands \\ \hline {\pgn atrm} & Remove queued {\pgn at} commands \\ \hline {\pgn batch} & Schedule jobs at low CPU loading \\ \hline \end{tabular} } \vspace{20pt} \item All of these can be run as {\pgn at} options: {\myss \begin{tabular}[t]{|>{\PBS\rr}p{90pt}|>{\PBS\rr}p{243pt}|} \hline Option & Purpose \\ \hline \hline {\cmdn -l} & Display list of queued {\pgn at} commands \\ \hline {\cmdn -d} & Remove queued {\pgn at} commands \\ \hline {\cmdn -b} & Schedule jobs at low CPU loading \\ \hline {\cmdn -f{\usb file}} & Specify script file in command-line \\ \hline {\cmdn -m} & Send mail after running {\pgn at}, whatever the {\cmdn stdout} or {\cmdn stderr} \\ \hline \end{tabular} } \vspace{20pt} \item The use of {\pgn at} is controlled by {\fn /etc/at.allow} and {\fn /etc/at.deny}~\footnote{UNIX NOTE: On System V these live in {\fn /usr/lib/cron/}} \end{itemize} % Nick: this could really be pruned down a bit. \section{Running commands regularly ({\pgn crontab})} \label{sec:tools_basic-crontab} \begin{itemize} \item {\pgn crontab} lets you submit job lists at regular times using the {\pgn crond} daemon \item 2 syntax formats: \begin{alltt} $ \textbf{crontab filename} $ \textbf{crontab [-u username] [options]} \end{alltt} \item Options, etc: \begin{table}[htbp] {\myts \begin{tabular}[t]{|p{110pt}|>{\PBS\rr}p{263pt}|} \hline Command & Purpose \\ \hline \hline {\cmdn crontab {\usb myfile}} & Install contents of {\usb myfile} (\verb|stdin| if no file specified) in appropriate directory \\ \hline {\cmdn crontab -r} & Remove the crontab for the current user \\ \hline {\cmdn crontab -l} & List (on \verb|stdout|) current user's {\pgn crontab}. (might be useful for editing a cron table) \\ \hline {\cmdn crontab -e} & Run a text editor on your crontab file \\ \hline \end{tabular} } \caption{{\normalsize \pgn crontab} usage} \label{tab:crontab-usage} \end{table} \item Examples of Crontab Entries {\myss \begin{verbatim} 01 * * * * root run-parts /etc/cron.hourly 02 4 * * * root run-parts /etc/cron.daily 22 4 * * 0 root run-parts /etc/cron.weekly 42 4 1 * * root run-parts /etc/cron.monthly # LW poll client1 for mail 0 10,12,16,18 * * 1-5 root /www/bin/client1_poll LW 16/09/1998 - Hylafax cron stuff ... 0 0 * * * root /usr/local/sbin/faxqclean 10 0 * * * fax /usr/local/sbin/faxcron -info 7 [0-59/10] 9-18 * * 1-5 root /usr/local/bin/domail \end{verbatim} } \end{itemize} \section{Evaluate expressions ({\pgn expr})} \label{sec:linux-unix-tools-evaluate-expressions} \begin{itemize} \item {\pgn expr} is used to evaluate expressions, like {\pgn bash} arithmetic expressions, e.g., {\uin echo \$((1 + 2))} \item Takes arguments and operators on the command line \item Prints the result \item Also returns true or false depending on the result; can be tested with shell---see example with the \texttt{while} loop below. \item Watch out for special meaning to shell of characters like {\kbk*} and {\kbk<} or {\kbk>} {\myss \begin{verbatim} $ expr 1 + 2 3 $ expr 6 \* 7 #must escape the '*' 42 $ expr 5 + 10 / 2 10 $ expr \( 5 + 10 \) / 2 7 $ i=10 $ i=`expr $i + 1` $ echo $i 11 \end{verbatim} %$ {\pgn expr} prints 1 for true comparisons, 0 for false. } \item Has some string manipulation facilities too: {\myss \begin{verbatim} $ expr index abcdefg d 4 $ expr substr abcdefghijk 3 3 cde \end{verbatim} } \item Sometimes used in shell scripts for looping; \texttt{expr} returns false if the expression is null or 0, and true otherwise: {%\myss \begin{verbatim} i=0 while expr $i \< 20 >/dev/null do echo $i i=$(expr $i + 1) done \end{verbatim} \item See \texttt{info expr} for details. } \end{itemize} \section{Linux Printing} \label{sec:basic-linux-unix-tools-linux-printing} \begin{itemize} \item Two main printing sytems: \begin{itemize} \item Common Unix Printing System (\CUPS) \url{http://www.cups.org/} \item LPRng \url{http://www.lprng.com/} \end{itemize} \item Both currently provided on Red Hat Linux 8.0 and 9 \item Only \CUPS provides on Fedora Core 1+. \begin{itemize} \item Can select either system with \texttt{redhat-switch-printer} command \end{itemize} \item Expect \CUPS to be more prevalent in future \end{itemize} \section{LPRng and CUPS} \label{sec:lprng-and-CUPS} \begin{itemize} \item Completely network-oriented \item Any printer can be made available to any client (machine and application) \item All print jobs are sent to a queue \item Queues can be viewed, edited, maintained from anywhere \begin{itemize} \item Subject to permission \end{itemize} \item Formatted files can be sent straight to queues \item Both \CUPS and LPRng both share common printing commands \end{itemize} \section{Main Printing Tools} \label{sec:basic-linux-unix-tools-main-printing-tools} \begin{itemize} \item {\pgn lpr} sends job to the queue for a named printer \item {\pgn lpq} returns info about jobs in a queue \item {\pgn lprm} removes unwanted jobs from a queue \item {\pgn lpc} enables system administrator to control the operation of the printing system \begin{itemize} \item see {\cmdn man lpc} for details \end{itemize} \item Desktop environments may offer ``drag `n' drop'', visual facilities, etc \end{itemize} \section{Using {\pgn lpr}} \label{sec:basic-linux-unix-tools-using-lpr} \begin{itemize} \item Syntax: \begin{verbatim} lpr [options] file ... \end{verbatim} \item Main Options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\mns \begin{tabular}{|l|p{313pt}|} \hline Flag & Options \\ \hline \hline {\cmdn -P} & Name of the printer to send the job to \\ {\cmdn -{\usb n}} & Print {\usb n} copies of the document \\ {\cmdn -m} & Send mail on completion \\ \hline \end{tabular} } \caption{Main {\pgn lpr} options} \label{tab:main-lpr-options} \end{center} \end{table} \vspace{-10pt} \item Example: \begin{verbatim} $ lpr -Pdjrmt -2 filetypes.txt \end{verbatim} %$ \end{itemize} \section{Using {\pgn lpq}} \label{sec:basic-linux-unix-tools-using lpq} \begin{itemize} \item Syntax: \begin{verbatim} lpq [options] \end{verbatim} \item Options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\mns \begin{tabular}{|l|p{313pt}|} \hline Flag & Options \\ \hline \hline {\cmdn -P} & Name of the printer/queue to interrogate \\ {\cmdn -l} & Get info on each file within a job \\ \hline \end{tabular} } \caption{{\pgn lpq} options} \label{tab:lpq-options} \end{center} \end{table} \vspace{-10pt} \item Example: \begin{verbatim} $ lpq -Pdjrmt -l \end{verbatim} %$ \end{itemize} \section{Using {\pgn lprm}} \label{sec:basic-linux-unix-tools-using-lprm} \begin{itemize} \item Syntax: \begin{verbatim} lprm [options] \end{verbatim} \item Options: \vspace{10pt} \begin{table}[htbp] \begin{center} {\mns \begin{tabular}{|l|p{313pt}|} \hline Flag & Options \\ \hline \hline {\cmdn -P} & Remove jobs from named printer/queue \\ {\cmdn -} & Remove all jobs belonging to yourself \\ {\cmdn {\usb user}} & Remove all jobs belonging to {\usb user} \\ {\cmdn {\usb n}} & Remove job number {\usb n} \\ \hline \end{tabular} } \caption{{\pgn lprm} options} \label{tab:lprm-options} \end{center} \end{table} \vspace{-10pt} \item Example: \begin{verbatim} $ lprm -Pdjrmt -davef \end{verbatim} %$ \end{itemize} \section{Printing Information} \label{sec:printing-information} \begin{itemize} \item This is a bare introduction \item See chapter 8 of the \emph{Red Hat Getting Started Guide} (for Red hat 9), and \item chapter 27 of the \emph{Red Hat Customization Guide} %\url{http://www.redhat.com/docs/manuals/linux/RHL-8.0-Manual/custom-guide/ch-printing.html} \item All these are available on the documentation \CDROM, or can be downloaded from \url{http://www.redhat.com/docs/manuals/linux/}. \end{itemize} \section{Basic Tools Exercises} \label{sec:basic-linux-unix-tools-exs} {\normalsize In these exercises, you will combine simple tools together using \emph{pipes}. Do this one step at a time, and check the results as you go. \begin{enumerate} \item {\em Find and Locate Files}\\ Use first {\pgn find} \emph{then} {\pgn locate} to do each of the following. First read \S\vref{sec:basic-linux-unix-tools-find} to \S\vref{sec:basic-linux-unix-tools-locate}, especially \S\vref{sec:find-examples}. Also, please read \S\vref{sec:basic-linux-unix-tools-tr} and \S\vref{sec:basic-linux-unix-tools-egs-tr} before doing part \ref{itm:translate}. \begin{enumerate} \item Display all the filenames under {\fn /usr/sbin}. \item Display all the filenames under {\fn /usr/sbin} begining with a lowercase `{\kbk c}'. \item \label{itm:translate}Repeat the previous question, but {\em translate} the output to uppercase. \item Display all the files under {\fn /usr/sbin} which are over 5k in size in uppercase. \end{enumerate} \item {\em Display Parts of Files} Note that the file \texttt{mime.types} lists the standard names used for different file types in both http and email. Before sending any data, a web server sends a header which includes the \emph{mime type}. That is how the web browser knows what to do with the data (i.e., how to display it or play it). Similarly, email containing attachments puts a mime type header before each attachment. That is how the email client knows what to do with the attachment (such as to automatically execute it and infect the machine with a worm). \begin{enumerate} \item Display the first 10 lines of the file {\fn /etc/mime.types} \item Display the last 10 lines of {\fn /etc/mime.types} \item Display the first 25 lines of {\fn /etc/mime.types} \item Display {\fn /etc/mime.types} one screen at a time \item While viewing {\fn /etc/mime.types} page-by-page, search for `html' \end{enumerate} \item {\em Classify, Count and Compare Files} \begin{enumerate} \item Find out what file types you have in the following directories and below. Please read \S\vref{sec:basic-linux-unix-tools-file}. Please also see the example on the bottom of \S\vref{sec:basic-linux-unix-tools-find}. \begin{enumerate} \item {\fn /etc} \item {\fn /usr/bin} \end{enumerate} \item Repeat the previous question, but this time: \begin{enumerate} \item Re-direct {\fn /etc} listing to new file {\fn filetypes.txt} \item Append the listing for {\fn /usr/bin} to {\fn filetypes.txt}. Please refer to \S\vref{sec:basic-shell-and-tools-approach-output-redirection}. \end{enumerate} \item Build a tool (i.e. write a command) to find out how many files are in the {\fn /usr/bin} directory. Hint: consider using \texttt{wc}. \item Create two new files from listings of 2 user's home directories, then find the differences between them. To do this, you could: \begin{itemize} \item Find a neighbour you can work with, and open a terminal window on their computer \item In that terminal window, type: \begin{alltt} $ \textbf{su - 012345678} \end{alltt}%$ (assuming your user \ID is 012345678). Of course, you need to enter your password. \item Make a list of files from your home directory into \texttt{/tmp}, making sure that the file names do not have \texttt{/home/012345678} in front of them, or otherwise your files will all seem to have different names! \item Compare your file list with that generated by your neighbour, who should also put their file list into \texttt{/tmp}. \end{itemize} %\item If you are feeling adventurous, use {\pgn diff} and {\pgn patch} \item Use {\pgn diff} and {\pgn patch} to make the two files created in the last question identical. (Check {\cmdn man patch}) %% \item If you are feeling very adventurous, use {\pgn diff} and {\pgn ed} %% to make the two files created in the last question identical. (Check %% {\cmdn man ed}) \end{enumerate} %\item {\em Regular Expressions} \item {\em\cmdn grep} Use the {\fn filetypes.txt} file that you created before, and do the following. Please read \S\vref{sec:basic-linux-unix-tools-grep} and \S\vref{sec:basic-linux-unix-tools-grep-examples} first. \begin{enumerate} \item List all the lines that contain `directory' \item List all the lines that don't contain `directory'. \item Find out how many files {\em are} directories, then find out how many aren't. \item Why does the following give an error message (try redirecting the output to \path{/dev/null} so you can see the error). \begin{alltt} $ \textbf{grep ASCII text filetypes.txt} \end{alltt}%$ \item Find out how many {\tt English text} files are listed in the {\fn filetypes.txt} file. \end{enumerate} \item {\em Sorting} \begin{enumerate} \item Sort the {\fn filetypes.txt} file into reverse alphabetical order on the first field. Please see \S\vref{sec:basic-linux-unix-tools-sort} and \S\vref{sec:basic-linux-unix-tools-sort-examples} first. You may notice that capital and lowercase letters are sorted independently, e.g. `{\tt A}' comes before `{\tt a}'. \item Repeat the first sorting exercise but ignoring case differences \item Sort the {\fn filetypes.txt} files into alphabetical order on the second field (the file type). \end{enumerate} \end{enumerate} \section{Basic Tools Solutions} \label{sec:basic-linux-unix-tools-solutions} \includeversion{Solutions}% \excludeversion{noSolutions}% \begin{Solutions} \begin{enumerate} \item {\em Find and Locate Files} \begin{enumerate} \item Either \begin{alltt} $ \textbf{find /usr/sbin} \end{alltt} %$ or \begin{alltt} $ \textbf{locate '/usr/sbin/*'} \end{alltt} %$ Note that the quotes are very important. If you leave them out, the program will run much more slowly, and the output will be wrong. Why? \item Either \begin{alltt} $ \textbf{find /usr/sbin -name "c*"} \end{alltt} %$ Why is {\cmdn find /usr/sbin/c*} wrong? Why are the quotes important around the {\cmdn c*}? or \begin{alltt} $ \textbf{locate '/usr/sbin/c*'} \end{alltt}%$ The quotes are \emph{really} important for speed and correctness. Why? If you do \begin{alltt} $ \textbf{locate /usr/bin/c\bs* | wc -w} 23 \end{alltt}% Very fast because only lookup one pattern in the database. \begin{alltt} $ \textbf{locate /usr/sbin/c* | wc -w} 30 \end{alltt}%$ Very slow because need look up 23 patterns in the database. Many file names are shown twice; for example, if you do: \begin{alltt}% $ \textbf{locate /usr/bin/cc /usr/bin/ccexample} /usr/bin/cc /usr/bin/ccexample /usr/bin/ccexample \end{alltt}%$ We get three results, not two, since \path{/usr/bin/cc} matches \path{/usr/bin/ccexample} as well as itself. \item Either \begin{alltt} $ \textbf{find /usr/sbin -name c\bs* | tr 'a-z' 'A-Z'} \end{alltt} %$ or \begin{alltt} $ \textbf{locate '/usr/sbin/c*' | tr 'a-z' 'A-Z'} \end{alltt} %$ \item \begin{alltt} $ \textbf{find /usr/sbin -size +5k | tr 'a-z' 'A-Z'} \end{alltt} %$ You should check that the size is correct. One way to do that is: \begin{alltt} $ \textbf{find /usr/sbin -size +5k -ls | sort -k5nr} \end{alltt} %$ What are the arguments to {\cmdn sort} for? Try looking at the output of {\cmdn find /usr/sbin -size +5k -ls} first. \end{enumerate} \item {\em Display Parts of Files} \begin{enumerate} \item \begin{alltt} $ \textbf{head /etc/mime.types} \end{alltt}%$ \item \begin{alltt} $ \textbf{tail /etc/mime.types} \end{alltt}%$ \item \begin{alltt} $ \textbf{head -n 25 /etc/mime.types} \end{alltt}%$ \item Use one of the following \begin{alltt} $ \textbf{less /etc/mime.types} \end{alltt}%$ or \begin{alltt} $ \textbf{more /etc/mime.types} \end{alltt} %$ \item While in one of the above, type {\uin /html {\kbk }} \end{enumerate} \item {\em Classify, Count and Compare Files} \begin{enumerate} \item Use these commands: \begin{enumerate} \item \begin{alltt} $ \textbf{find /etc -exec file \{\} \bs;} \end{alltt}%$ Note that the following will not execute \texttt{file} on files in subdirectories of \texttt{/etc}: \begin{alltt} $ \textbf{file /etc/*} \end{alltt} %$ \item \begin{alltt} $ \textbf{find /usr/bin -exec file \{\} \bs;} \end{alltt}%$ \end{enumerate} \item Use these commands \begin{enumerate} \item \begin{alltt} $ \textbf{find /etc -exec file \{\} \bs; > filetypes.txt} \end{alltt}%$ \item \begin{alltt} $ \textbf{find /usr/bin -exec file \{\} \bs; >> filetypes.txt} \end{alltt}%$ \end{enumerate} \item The easiest solution is \begin{alltt} $ \textbf{echo /usr/bin/* | wc -w} \end{alltt}%$ But that will count any file with a space in its name as two files. This will count all files only once: \begin{alltt} $ \textbf{ls -d /usr/bin | wc -l} \end{alltt}%$ Note that when \texttt{ls} sends its output to a pipe, it always puts it in one column, so that there is one file per line. See \texttt{man~ls}. \item Something like this: \begin{alltt} $ \textbf{cd} $ \textbf{find . > /tmp/test1.txt} $ \textbf{cp /tmp/test1.txt \(\sim\)} \end{alltt}%$ Now another student logs into another window: \begin{alltt} $ \textbf{su - 012345678} Password: $ \textbf{find . > /tmp/test2.txt} $ \textbf{cp /tmp/test1.txt /tmp/test2.txt \(\sim\)} $ \textbf{diff -u test2.txt test1.txt > file-diff.patch} $ \textbf{less file-diff.patch} $ \textbf{exit} \end{alltt} And you can copy the second students file list into your own directory: \begin{alltt} $ \textbf{cp /tmp/test2.txt \(\sim\)} $ \textbf{diff -u test1.txt test2.txt > my-file-diff.patch} $ \textbf{less file-diff.patch} \end{alltt}%$ Make sure you understand the format of \texttt{diff -u}, and given output from \texttt{diff} and the original file, can determine what the second file contains. %% \begin{alltt} %% $ \textbf{ls /home/davef > test1.txt} %% $ \textbf{ls /home/mikeb > test2.txt} %% $ \textbf{diff test1.txt test2.txt} %% \end{alltt}%$ \item This technique is very important in software development and software packaging: \begin{alltt} $ \textbf{diff -u test1.txt test2.txt > test.patch} $ \textbf{patch < test.patch} patching file test1.txt \end{alltt} %% \item This solution uses the {\cmdn -{}-ed} option to {\pgn diff}, and the %% {\pgn ed} line-editor. %% \begin{alltt} %% $ \textbf{diff --ed test1.txt test2.txt > differences.txt} %% $ \textbf{cat >> differences.txt %% w %% q %% d} %% $ \textbf{cat differences.txt | ed test1.txt} %% \end{alltt} %% %$ %% You could instead use the {\pgn sed} %% stream editor to perform the %% editing in one pipeline. \end{enumerate} %\item {\em Regular Expressions} \item {\em\cmdn grep} \begin{enumerate} \item \begin{alltt} $ \textbf{grep directory filetypes.txt} \end{alltt} %$ \item \begin{alltt} $ \textbf{grep -v directory filetypes.txt} \end{alltt} %$ \item Use either \begin{alltt} $ \textbf{grep -c directory filetypes.txt} \end{alltt}%$ or \begin{alltt} $ \textbf{grep directory filetypes.txt | wc -l} \end{alltt}%$ then either \begin{alltt} $ \textbf{grep -cv directory filetypes.txt} \end{alltt}%$ or \begin{alltt} $ \textbf{grep -v directory filetypes.txt | wc -l} \end{alltt}%$ \item Without escaping the space between {\em ASCII} and {\em text} the shell assumes the pattern has ended and takes {\em text} as a filename to look for; hence the error about a non-existing file. {\pgn grep} continues, however, showing lines that match "ASCII" in the files it can find. What you probably wanted was: \begin{alltt} $ \textbf{grep "ASCII text" filetypes.txt} \end{alltt} %$ \item \begin{alltt} $ \textbf{grep -c "English text" filetypes.txt} \end{alltt} %$ \end{enumerate} \item {\em Sorting} \begin{enumerate} \item \begin{alltt} $ \textbf{sort -r filetypes.txt} \end{alltt} %$ \item \begin{alltt} $ \textbf{sort -fr filetypes.txt} \end{alltt} %$ \item \begin{alltt} $ \textbf{sort -k2 filetypes.txt} \end{alltt} %$ \end{enumerate} \end{enumerate} \end{Solutions} \begin{noSolutions} We will provide solutions soon. \end{noSolutions} \label{endofchapter-basic-linux-unix-tools} } % Ends {\normalsize } % end {\mns from chapter start \excludeversion{Solutions}% \includeversion{noSolutions}% %%% Local Variables: %%% mode: latex %%% TeX-master: "toolsmaster" %%% End: