CompTIA Linux+ (XK0-006) · chapter 4 of 14
Week 4: The shell, sharpened
In this chapter Objectives 1.5, 2.1, 5.2
Objective 1.5
Environment, paths and startup files
Six variables the exam names
Variables shape every command you run. See them with echo $NAME or env.
- PATH: colon-separated directories searched for commands, in order. The current directory is NOT in it
- HOME: your home directory (what ~ means). USER: your login name
- SHELL: your login shell, e.g. /bin/bash
- PS1: the prompt's format (\u@\h:\w\$ gives ranger@web01:~$)
- DISPLAY: which X display GUI programs draw on (:0, or forwarded over SSH)
Exam tip export makes a variable visible to programs you start. Without export, it stays in this shell only.
Absolute and relative paths
An absolute path starts at / (or ~, which expands to an absolute home path) and works from anywhere. A relative path starts where you are: . is this directory, .. the parent. cd - jumps back to the previous directory (it's stored in $OLDPWD).
$ cd /etc/nginx $ cd ../ssh # now /etc/ssh $ cd - # back to /etc/nginx $ ./deploy.sh # run from here
Startup files: which one runs?
A login shell (SSH in, console login) reads /etc/profile, then the first of ~/.bash_profile, ~/.bash_login or ~/.profile. An interactive non-login shell (a new terminal tab, running bash) reads ~/.bashrc. Ubuntu's ~/.profile sources ~/.bashrc, so aliases end up everywhere. source file (or . file) runs a file in the current shell, so changes apply right now, without logging out.
Sam: Edited .bashrc and nothing changed? source ~/.bashrc, or open a new shell.
Exam tip Put aliases and functions in ~/.bashrc. Put login-only things (PATH additions run once) in ~/.bash_profile or ~/.profile.
Objective 1.5
Streams and redirection
Three streams
Every program gets standard input (0), standard output (1) and standard error (2). Redirection rewires them.
cmd > f stdout to f (overwrite) cmd >> f stdout, append cmd 2> f stderr to f cmd > f 2>&1 both to f cmd &> f both to f (bash) cmd < f f as stdin cmd1 | cmd2 stdout into next stdin cmd 2>/dev/null discard errors
Exam tip Order matters: > file 2>&1 sends both to the file. 2>&1 > file leaves errors on the screen.
Here documents and here strings
A here document (<<) feeds several lines into a command until a marker word. A here string (<<<) feeds one string. Both save temporary files.
$ cat > motd.txt <<EOF Authorized Kibble staff only. EOF $ tr a-z A-Z <<< "woof" WOOF
Exam tip The objectives list here docs with <<<. Strictly, << is a here document and <<< is a here string. Know both.
tee: write and keep watching
tee copies its input to a file and to the screen, so a pipeline can save and continue. It's also the clean way to write a root-owned file: sudo echo x > /etc/file fails, because your own shell opens the file before sudo runs. echo x | sudo tee /etc/file works, because tee runs as root. Add -a to append.
Exam tip "Permission denied" on sudo cmd > /etc/... is the redirect running as you, not a broken sudo.
Check yourself 1A nightly script's errors keep landing in Sam's email. He wants normal output in /var/log/sync.log and errors thrown away. Which line does that?
- sync.sh 2>> /var/log/sync.log > /dev/null
- sync.sh &> /var/log/sync.log
- sync.sh >> /var/log/sync.log 2>/dev/null
- sync.sh | tee /var/log/sync.log
Show the answer
Answer: C. sync.sh >> /var/log/sync.log 2>/dev/null
>> appends stdout to the log; 2>/dev/null discards stderr. Each stream gets its own redirect.
Objective 1.5
The text toolkit
Slicing lines
Most logs are lines of fields. Pick the tool for the job.
- grep pattern: keep matching lines (-i ignore case, -v invert, -c count, -r recurse)
- cut -d: -f1: pick fields by a fixed delimiter
- awk '{print $1}': pick whitespace fields; -F: sets the separator; $NF is the last field
- sed 's/old/new/g': stream edit; -i edits a file in place
- tr a-z A-Z: translate or delete characters (tr -d '\r')
Exam tip cut needs a single-character delimiter. Columns separated by runs of spaces? Use awk.
Sorting, counting and viewing
sort orders lines (-n numeric, -h human sizes like 2G, -r reverse). uniq collapses repeated adjacent lines (-c counts them), so sort first. wc -l counts lines. head/tail show the start/end (tail -f follows a growing log). less pages forward and back with search; more is the older forward-only pager. cat prints files.
$ grep 'Failed password' /var/log/auth.log |
awk '{print $(NF-3)}' | sort | uniq -c |
sort -rn | head -3
412 203.0.113.9
37 198.51.100.4
5 192.0.2.77Exam tip Classic pipe: grep | awk | sort | uniq -c | sort -rn | head.
Building and repeating commands
xargs turns input lines into arguments: find /tmp -name '*.tmp' | xargs rm. echo prints text; printf prints formatted text (printf '%-10s %5d\n' web01 42). bc does math (echo '2^10' | bc). uname -r shows the kernel version (-a everything). history lists past commands; !! repeats the last one (sudo !!), !42 runs number 42, !ssh the last one starting with ssh. alias ll='ls -l' makes shortcuts.
Exam tip sudo !! is the classic fix after "Permission denied".
vi/vim and nano
nano shows its keys on screen: Ctrl+O saves, Ctrl+X exits, Ctrl+W searches. vi/vim is on every server, so learn its modes. Normal mode moves and edits (dd deletes a line, yy copies, p pastes, u undoes, /word searches). i enters insert mode to type; Esc goes back. Commands start with a colon: :w save, :q quit, :wq save and quit, :q! quit without saving.
Ranger: paws at the Esc key, helpfully
Exam tip Stuck in vim? Esc, then :q! and Enter. Nothing saved, nothing broken.
Check yourself 2Priya's list has the same IP on many lines, not next to each other. Which pipeline counts how many times each IP appears?
- uniq -c ips.txt
- wc -l ips.txt
- sort -u ips.txt | wc -l
- sort ips.txt | uniq -c
Show the answer
Answer: D. sort ips.txt | uniq -c
uniq compares each line with the one before it, so you sort first to put identical lines together. Then -c adds a count.
Objective 2.1
Managing files and directories
Everyday utilities, precisely
You know most of these; the exam tests the options.
- cd dir moves you; cd alone goes home.
cp -acopies keeping owners, permissions and times (an archive copy); -r for directories - mv moves or renames;
rm -rdeletes a tree; rmdir removes only EMPTY directories mkdir -pmakes parents as needed; touch creates an empty file or updates its timels -l / -a / -i / -h: long, hidden, inode numbers, human sizes. pwd shows where you are- file names a file's type from its content, not its extension
- stat shows inode, links, owner, and atime/mtime/ctime
Exam tip mtime = content changed. ctime = metadata (permissions, owner) changed. atime = last read.
Finding and comparing
find searches the live tree by any property: find /var -type f -size +100M -mtime -7 -exec ls -lh {} \;. locate is much faster but searches a database built by updatedb, so brand-new files are missing until it runs again. diff -u shows changes line by line (the patch format). sdiff shows two files side by side. lsof lists open files: lsof /var/log/app.log shows who holds it, and lsof -i :80 shows who uses a port.
Exam tip Just created the file and locate can't see it? updatedb hasn't run yet. Use find.
Hard links and symbolic links
A hard link is a second name for the same inode: same data, same permissions. Deleting one name leaves the data until the link count reaches 0. Hard links can't cross filesystems or point to directories. A symbolic link (ln -s target name) is a tiny file holding a path. It can cross filesystems and point to directories, but it breaks (dangles) if the target moves.
$ ln report.txt report-hard $ ln -s /srv/shop/current shop $ ls -li 1311 -rw-r--r-- 2 report.txt 1311 -rw-r--r-- 2 report-hard 1402 lrwxrwxrwx 1 shop -> /srv/shop/current
Exam tip Same inode number and a link count of 2 = hard link. An l in the first column and an arrow = symlink.
Device files in /dev
The first letter of ls -l tells you the device type. Block devices (b) move data in blocks with random access: disks, partitions, LVs (/dev/sda, /dev/nvme0n1). Character devices (c) stream bytes in order: terminals, serial ports (/dev/ttyS0). Special character devices are kernel helpers: /dev/null discards everything, /dev/zero gives endless zero bytes, /dev/urandom and /dev/random give random bytes.
$ ls -l /dev/sda /dev/null brw-rw---- 1 root disk 8, 0 /dev/sda crw-rw-rw- 1 root root 1, 3 /dev/null
Exam tip The two numbers (8, 0) are the major (driver) and minor (which device) numbers.
Check yourself 3Sam deletes /srv/data/price-list.csv. A hard link to it, /home/rosa/prices.csv, existed on the same filesystem. What happens to Rosa's file?
- It keeps working, with all its data
- It becomes a broken link pointing at nothing
- It's deleted too, because both names share an inode
- It turns into an empty file of 0 bytes
Show the answer
Answer: A. It keeps working, with all its data
Both names point at the same inode. rm drops the link count from 2 to 1, so Rosa's name still reaches all the data.
Objective 5.2
When the shell can't find anything
PATH misconfiguration
"command not found" for a program that's clearly installed usually means PATH is wrong. The classic mistake is assigning instead of appending: PATH=/opt/app/bin replaces the whole list, so even ls vanishes. Diagnose with echo $PATH, then type ls or which ls. Fix the line to PATH="$PATH:/opt/app/bin", and put system-wide additions in /etc/profile.d/*.sh. Scripts and cron jobs get a minimal PATH, so use full paths there.
$ export PATH=/opt/kibble/bin $ ls bash: ls: command not found $ /usr/bin/ls # full path still works
Exam tip Full paths always work. If /usr/bin/ls runs but ls doesn't, PATH is the problem.
Go deeper
More on the objectives in this chapter, in the same exam-ready detail.
Objective 1.5 · Paths: absolute (~, /), relative (., .., -)
Absolute and relative paths
The symbols
Paths are built from a few special symbols:
- /: the root of the filesystem; a path starting with / is absolute (/etc/ssh/sshd_config)
- ~: your home directory (~/notes is /home/you/notes)
- .: the current directory (./script.sh runs a script here)
- ..: the parent directory
- - (with cd): go back to the previous directory (cd -)
Remember
Absolute paths work from anywhere; relative paths depend on where you are (pwd shows that). Scripts and cron jobs should use absolute paths because their working directory may not be what you expect.
Objective 1.5 · Shell environment configurations: .bashrc, .bash_profile, .profile
Shell startup files
Which file runs when
Bash reads different files depending on how the shell started:
- Login shell (SSH login, console login): reads /etc/profile, then the first of ~/.bash_profile, ~/.bash_login or ~/.profile
- Interactive non-login shell (a new terminal window, running bash): reads ~/.bashrc (and /etc/bashrc or /etc/bash.bashrc)
- Most .bash_profile files source .bashrc so both kinds get the same settings
What goes where
Environment variables like PATH: .bash_profile/.profile. Aliases, prompt and functions: .bashrc. System-wide for all users: /etc/profile or files in /etc/profile.d/. Apply changes now with source ~/.bashrc.
Exam tip Alias works in a new terminal but not over SSH: it's in .bashrc and .bash_profile doesn't source .bashrc.
Objective 1.5 · Channel redirection: here docs (<<<)
Here documents and here strings
Here document (<<)
Feeds several lines to a command's input, ending at a marker:
- cat <<EOF > /etc/motd
- Authorized use only
- EOF
- Variables are expanded unless the marker is quoted (<<'EOF')
Here string (<<<)
Feeds one string to standard input: grep root <<< "$line" or **bc <<< "2*21". The objectives write it as here docs (<<<); know both: << for a block of lines, <<<** for a single string.
Objective 1.5 · Text editors: vi/vim, nano
vi/vim and nano
vim survival
vim has modes. Normal mode (Esc) for commands; i to insert text; :w save; :q quit; :wq or ZZ save and quit; :q! quit without saving.
- dd delete a line, yy copy, p paste, u undo
- /text search, n next match
- :%s/old/new/g replace everywhere
- :set number show line numbers
nano
nano shows its shortcuts at the bottom (^ means Ctrl): Ctrl+O write (save), Ctrl+X exit, Ctrl+W search, Ctrl+K cut a line, Ctrl+U paste.
Exam tip Stuck in vim: press Esc, type :q! and Enter.
Objective 2.1 · Links: symbolic link, hard link
Hard links and symbolic links
Symbolic (soft) link
ln -s /opt/app/current/bin/app /usr/local/bin/app. A small file that points to a path. Can cross filesystems and point to directories. If the target is deleted, the link breaks (dangling). ls -l shows it as l... -> target.
Hard link
ln /data/report.txt /backup/report.txt. Another name for the same inode: both names are equally real, and the data stays until the last name is deleted. Can't cross filesystems or link directories. ls -li shows the shared inode number and the link count.
Exam tip Need a link to a directory or across filesystems: symbolic. Need the data to survive deleting the original name: hard.
Practice questions
Answer in your head, then open the answer. Ranger's Terminal has 514 questions like these for Linux+, with mock exams.
Question 1Kibble's in-house tools are installed in /opt/kibble/bin. Sam wants to run them by name without breaking any existing commands. Which line should go in his ~/.bashrc?
- export PATH="/opt/kibble/bin"
- export HOME="$HOME:/opt/kibble/bin"
- alias PATH="/opt/kibble/bin"
- export PATH="$PATH:/opt/kibble/bin"
Show the answer
Answer: D. export PATH="$PATH:/opt/kibble/bin"
PATH is a colon-separated list searched in order. Appending with $PATH: keeps the existing directories; assigning only the new one hides every standard command.
Question 2Sam connects to a server with ssh -X so he can open a graphical log viewer, but the viewer says it cannot open a display. Which environment variable tells X programs where to draw?
- SHELL
- TERM
- PS1
- DISPLAY
Show the answer
Answer: D. DISPLAY
X clients connect to the display named in DISPLAY (for SSH forwarding usually localhost:10.0). If ssh -X forwarding fails, DISPLAY is not set.
Question 3Sam wants his prompt on production servers to show the user, host and current directory, like sam@db01:/etc$. Which variable controls this?
- PS1
- PATH
- USER
- HOME
Show the answer
Answer: A. PS1
PS1 is the primary prompt string, e.g. PS1='\u@\h:\w\$ ' for user, host and working directory.
Question 4Sam added alias ll='ls -lh' to ~/.bash_profile. It works after he logs in over SSH, but not in new terminal windows on his Linux desktop. Why?
- Aliases only work for the root user
- Desktop terminals start non-login shells, which read ~/.bashrc instead
- ~/.bash_profile is read only by zsh
- Desktop terminals read /etc/skel/.bashrc instead of the user's files
Show the answer
Answer: B. Desktop terminals start non-login shells, which read ~/.bashrc instead
Bash login shells read ~/.bash_profile (or ~/.bash_login, then ~/.profile). Interactive non-login shells read ~/.bashrc. Put aliases in ~/.bashrc and source it from ~/.bash_profile.
Question 5Rosa's account on an Ubuntu server always had settings in ~/.profile. After she created ~/.bash_profile for one new variable, her old ~/.profile settings stopped applying at SSH login. Why?
- ~/.profile is read only by graphical desktop sessions
- ~/.bash_profile resets every variable set earlier by /etc/profile
- bash stops at the first of .bash_profile, .bash_login, .profile
- SSH logins never read any profile files
Show the answer
Answer: C. bash stops at the first of .bash_profile, .bash_login, .profile
A bash login shell reads /etc/profile and then the first one it finds of ~/.bash_profile, ~/.bash_login and ~/.profile. Adding '. ~/.profile' inside ~/.bash_profile restores the old settings.
CompTIA, A+, Network+, Security+ and Linux+ are trademarks of CompTIA, Inc. Ranger Gamez is not affiliated with or endorsed by CompTIA. The practice questions are written to the published exam objectives; they are not real exam questions.