Shell and Other Basics
- Shell and Other Basics
How the shell turns what you type into action
The shell is the command-line interpreter that reads your input and hands it to the kernel. Understanding how it resolves commands (PATH), manages the environment, handles input and output (redirects and pipes), and escalates privilege (sudo) is what separates fumbling at a prompt from working fluently — and several of these mechanisms are security-relevant in their own right. The commands you navigate and edit with are all run through the shell.
This page covers PATH resolution, environment variables, the help system, I/O redirection, and the super-user tools (sudo/su) — the last of which connects directly to access control and the privilege-escalation paths attackers hunt for.
Command Path
When you type a command, the shell searches a list of directories to find the executable. This list is stored in the PATH environment variable.
How PATH works
echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
Directories are separated by :. The shell searches left to right and runs the first match it finds.
Viewing and modifying PATH
echo $PATH # current search path
which python3 # which executable would run
type ls # show how shell resolves 'ls' (alias, builtin, file)
command -v python3 # POSIX-compliant alternative to which
# Add a directory to PATH (for current session only)
export PATH="$HOME/bin:$PATH"
# Add permanently — append to your interactive shell's startup file.
# Kali's default shell is zsh, so use ~/.zshrc; on bash systems use ~/.bashrc.
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc # reload without logging out
ℹ️ The examples below write to
~/.zshrcbecause the course VM (Kali) ships zsh as the default interactive shell. If your shell is bash, substitute~/.bashrc— theexport/sourcemechanics are identical.
Locating executables
whereis ls # find binary, source, and man page
locate sshd # fast filesystem-wide search (uses database)
find /usr -name python3 -type f # find without database
Worked example — add a local scripts directory to PATH:
mkdir -p ~/bin
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Now scripts placed in ~/bin are available anywhere
⚠️ PATH order is a security boundary. The shell runs the first match, so a writable directory early in
PATH— or the current directory.— lets an attacker shadow a real command (ls,sudo) with a malicious one. Never put.inPATH, and never make aPATHdirectory world-writable. This is a classic privilege-escalation vector.
Environment Variables
Environment variables are key-value pairs inherited by every child process. They control the behavior of the shell and programs.
Reading variables
echo $HOME # home directory
echo $USER # current username
echo $SHELL # current shell
echo $PWD # current directory
echo $LANG # locale setting
env # list all environment variables
printenv HOME # print a specific variable
Common environment variables
| Variable | Meaning |
|---|---|
PATH |
Colon-separated list of executable search directories |
HOME |
Current user’s home directory |
USER |
Current username |
SHELL |
Path to the user’s shell |
LANG / LC_ALL |
Locale and character encoding |
EDITOR |
Default text editor for programs that open one |
PAGER |
Default pager (typically less) |
TERM |
Terminal type |
PS1 |
Shell prompt string |
TMPDIR |
Temporary file directory |
Setting and exporting variables
# Set for current shell only
MYVAR="hello"
# Export to make available to child processes
export MYVAR="hello"
# Set for one command only
EDITOR=vim git commit
# Unset a variable
unset MYVAR
# Set at login (persists across sessions)
echo 'export EDITOR=vim' >> ~/.zshrc
Variable expansion
name="world"
echo "Hello, $name" # Hello, world
echo "Hello, ${name}!" # Hello, world! (braces delimit variable name)
echo "${name:-default}" # use 'default' if name is unset or empty
echo "${#name}" # length of variable value
echo "${name^^}" # uppercase (bash 4+)
Worked example — run a command with a modified environment:
# Run a command with a clean environment
env -i HOME=/tmp PATH=/usr/bin:/bin bash --norc
# Run a program with one extra variable
DEBUG=1 ./myscript.sh
Command Help
Linux has several layers of built-in documentation.
man — manual pages
man ls # manual page for ls
man 5 passwd # section 5 (file formats) for passwd
man -k keyword # search man page names (like apropos)
man -K keyword # full-text search across all man pages
Man page sections:
| Section | Content |
|---|---|
| 1 | User commands |
| 2 | System calls |
| 3 | Library functions |
| 4 | Special files (/dev) |
| 5 | File formats and configuration |
| 6 | Games |
| 7 | Miscellaneous (conventions, signals) |
| 8 | System administration commands |
info — GNU info pages
info coreutils # info page for coreutils package
info bash # comprehensive bash documentation
Built-in help
ls --help # GNU coreutils style
bash --help # shell help
help cd # help for bash builtins
help # list all bash builtins
type -a ls # all definitions of 'ls' (alias, function, path)
apropos and whatis
apropos compress # search descriptions of all man pages
whatis tar # one-line description
Worked example — find the right tool for a task:
# Find commands related to "network"
man -k network | grep -i interface
apropos socket | head -10
Redirects
Redirects control where command input comes from and where output goes.
Standard streams
Every process has three standard file descriptors:
| Descriptor | Name | Default |
|---|---|---|
0 |
stdin | Keyboard |
1 |
stdout | Terminal |
2 |
stderr | Terminal |
Output redirection
ls -l > files.txt # redirect stdout to file (overwrite)
ls -l >> files.txt # redirect stdout, appending
ls /bad 2> errors.txt # redirect stderr to file
ls /bad 2>> errors.txt # append stderr
ls -l /bad > out.txt 2>&1 # redirect both stdout and stderr to file
ls -l /bad &> out.txt # bash shorthand for above
ls -l /bad 2>/dev/null # discard stderr (send to null device)
Input redirection
sort < names.txt # read stdin from file
wc -l < file.txt # count lines in file via stdin
Here documents and here strings
# Here document: feed multiple lines to a command
cat << EOF
line one
line two
EOF
# Here string: feed a single string to stdin
grep "pattern" <<< "some string to search"
# Here document to a file
cat << 'EOF' > /tmp/script.sh
#!/bin/bash
echo "Hello"
EOF
Pipes
Pipes (|) connect stdout of one command to stdin of the next.
ps aux | grep nginx # find nginx processes
ls -lh | sort -k5 -rh # list files sorted by size
cat /var/log/syslog | grep -i error | tail -20
Worked example — capture both output and errors, view live and save:
# Run a build, show output on terminal AND save to log file
make 2>&1 | tee build.log
# Run command, discard all output
./noisycmd &>/dev/null
Super User
The root account (UID 0) has unrestricted access to the system. Most distributions restrict direct root login and require sudo for privileged operations.
sudo — run commands as another user
sudo command # run as root
sudo -u alice command # run as user alice
sudo -i # start interactive root shell (login shell)
sudo -s # start root shell without login profile
sudo !! # repeat last command as root (bash history)
sudo -l # list allowed sudo commands for current user
sudo visudo # safely edit /etc/sudoers
su — switch user
su - # switch to root (full login environment)
su - alice # switch to alice's environment
su alice # switch to alice, keep current environment
exit # return to previous user
sudoers configuration
/etc/sudoers defines who can use sudo and for what. Always edit with visudo, which validates syntax before saving.
# Allow user 'alice' to run all commands as root
alice ALL=(ALL:ALL) ALL
# Allow group 'devops' to restart nginx without password
%devops ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx
# Allow user 'bob' to run specific commands
bob ALL=(ALL) /usr/bin/apt, /usr/bin/systemctl
Common sudoers patterns:
| Rule fragment | Meaning |
|---|---|
ALL=(ALL:ALL) ALL |
All hosts, all users/groups, all commands |
NOPASSWD: /path/cmd |
No password required for that command |
%groupname |
Applies to all members of the group |
Root shell via sudo
sudo su - # switch to root via sudo
sudo bash # start root bash shell
sudo -i # login shell as root
whoami # verify current user
id # show UID, GID, and groups
Worked example — safely grant a user limited sudo access:
# Edit sudoers safely
sudo visudo
# Add this line to let 'deploy' restart services only:
# deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart *, /bin/systemctl stop *
⚠️ Prefer
sudoover a permanent root shell.sudousage is logged to/var/log/auth.log(Debian/Ubuntu/Kali) or/var/log/secure(RHEL/Fedora), giving accountability — theAin AAA from security principles. Direct root logins leave a weaker audit trail, and an overly broad sudoers rule (especiallyNOPASSWDon a command that can spawn a shell) is one of the most common privilege-escalation findings — which is why attackers runsudo -lfirst thing.
Key takeaways
- The shell finds commands by searching
PATHleft to right and running the first match — soPATHorder and writability is a security boundary, not just convenience. - Environment variables are inherited by child processes;
exportmakes them available downstream, andVAR=value commandsets one for a single invocation. - The help system is layered:
man(with numbered sections),info,--help,helpfor builtins, andapropos/man -kto search. - Redirection wires up the three standard streams —
>/>>(stdout),2>(stderr),&>(both),<(stdin) — and pipes (|) chain stdout into the next command’s stdin. sudoruns single commands as root with logging and is preferred oversu/root shells;sudoers(edited withvisudo) defines who may do what — apply least privilege here.
References
- W. Shotts, The Linux Command Line — environment, redirection, and permissions chapters. https://linuxcommand.org/tlcl.php
bash(1)— the Bash reference manual (expansion, redirection, builtins). https://www.gnu.org/software/bash/manual/bash.htmlsudoers(5)andsudo(8)man pages. https://www.sudo.ws/docs/man/sudoers.man/man(1)and the Linux man-pages project. https://www.kernel.org/doc/man-pages/
Related course pages: Navigation Basics · Editing Files · Working with Files · User Management · Access Control and Authorization · Host Security
🛠️ Maintenance note: shell mechanics are stable. The examples target Kali’s default zsh (
~/.zshrc); if the course VM’s default shell changes, update those rc-file paths. Also watch the sudo log path, which differs by distro family.