Shell productivity¶
Level 1 · Chapter 7 · ⏱️ ~40 min read · Prerequisites: Pipes and redirection, Finding files
The difference between someone who tolerates the terminal and someone who is fast in it is rarely knowledge of more commands. It is history search, editing shortcuts, aliases, small functions, and a well-organized ~/.bashrc. This chapter covers all of them, plus how bash starts up, how environment variables reach programs, and how PATH works.
Why it matters¶
Alex spends a morning debugging an ETL job and runs the same long command dozens of times:
python3 etl.py --input /srv/data/raw/2026-09-21 --output /srv/data/clean --log-level debug 2>&1 | tee -a etl.log
Each time, Alex presses Up fifteen times to find it, then holds Left for several seconds to change the date. A colleague watching over Alex's shoulder types Ctrl+R, etl, Enter: the command is back in half a second. Alt+B jumps back a word at a time; Ctrl+W deletes one.
Inspired, Alex adds export DATA_DIR=/srv/data to a new ~/.bash_profile. The next day, connected over SSH, every alias Alex relies on has vanished. Creating ~/.bash_profile made bash skip ~/.profile, which was the file that loaded ~/.bashrc.
Fast shell use is a set of small habits. Understanding the startup files is what keeps those habits working on every machine.
Concepts¶
Kinds of shells: interactive and login¶
Bash runs in different modes, and the mode decides which configuration files it reads.
- An interactive shell reads commands from you at a prompt. A non-interactive shell runs a script or a single
bash -c 'command'and exits. - A login shell is the first shell of a session, started when you log in: over SSH, at a text console (Ctrl+Alt+F3), or with
bash -l. A non-login shell is started from an existing session, such as each new terminal window on the Mint desktop.
| How you started bash | Interactive? | Login? |
|---|---|---|
| Opening Terminal on the Mint desktop | Yes | No |
ssh alex@mint |
Yes | Yes |
| Logging in on a text console | Yes | Yes |
bash -l or su - alex |
Yes | Yes |
Running ./script.sh |
No | No |
| A cron job or systemd service running a script | No | No |
You can check. The special variable $- lists the shell's active option letters, and it contains i in an interactive shell:
That is a desktop terminal: interactive (i), not a login shell.
Which startup files bash reads¶
flowchart TD
S["bash starts"] --> L{"Login shell?"}
L -- yes --> P["/etc/profile"]
P --> F{"First that exists:<br/>~/.bash_profile<br/>~/.bash_login<br/>~/.profile"}
F --> PR["Mint's ~/.profile<br/>sources ~/.bashrc"]
L -- no --> I{"Interactive?"}
I -- yes --> SB["/etc/bash.bashrc"]
SB --> B["~/.bashrc"]
I -- no --> N["No startup files<br/>(only $BASH_ENV if set)"]
The details:
- Login shells read
/etc/profile, then only the first of~/.bash_profile,~/.bash_login, and~/.profilethat exists. On Mint, only~/.profileexists by default, and it contains a block that loads~/.bashrcfor bash. That is how login shells also get your aliases. - Interactive non-login shells (your desktop terminals) read
/etc/bash.bashrcand then~/.bashrc. - Non-interactive shells (scripts) read nothing by default. That is why an alias from
~/.bashrcdoes not work inside a script, and why scripts should never depend on your personal configuration. - Your graphical session is started through
~/.profiletoo, so environment variables set there reach desktop apps, not just terminals.
The default ~/.bashrc on Mint starts with this guard, which stops it doing anything in a non-interactive shell:
What goes where¶
| Put this | In | Why |
|---|---|---|
Environment variables: PATH, EDITOR, DATA_DIR |
~/.profile |
Read once per login, inherited by every program, including GUI apps |
Aliases, functions, prompt (PS1), shell options (shopt), history settings |
~/.bashrc |
Only meaningful in interactive shells, and not inherited by child processes |
| Long lists of aliases | ~/.bash_aliases |
Mint's ~/.bashrc already loads it if it exists |
Common mistake
Creating ~/.bash_profile because a tutorial said so. Once it exists, login shells stop reading ~/.profile, and with it your ~/.bashrc loading. If you must have a ~/.bash_profile, make its first line [ -f ~/.profile ] && . ~/.profile.
Shell variables and environment variables¶
Every process has an environment: a list of NAME=value strings that it receives from its parent when it starts, and passes on to its own children. HOME, PATH, USER, LANG, and EDITOR are environment variables.
The shell also has shell variables, which live only inside that shell process. Assigning region=north creates a shell variable. export marks a variable so that it is copied into the environment of every command the shell starts.
flowchart LR
subgraph Shell["Your bash process"]
SV["region=north<br/>(shell variable)"]
EV["export DATA_DIR=/srv/data<br/>(environment variable)"]
end
Shell -- "starts" --> C["python3 etl.py<br/>sees DATA_DIR<br/>does not see region"]
Two facts follow from "copied at start":
- A child process cannot change its parent's variables. A script that runs
export X=1does not changeXin the shell that ran it. Its copy dies with it. - Changing a variable after a program has started does not affect that program.
How PATH lookup works¶
PATH is a colon-separated list of directories. When you type a command name without a /, bash searches those directories from left to right and runs the first executable file with that name. (Aliases, functions, and builtins are checked before PATH, as you saw in Finding files.)
/home/alex/.local/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
- The current directory is not in
PATH. That is a security feature: a malicious file namedlsin a download folder cannot hijack yourls. To run a program in the current directory, write./program. - Order matters. Putting
~/.local/binfirst lets your own version of a tool override the system's. - Bash remembers where it found each command in a hash table, so it does not search
PATHevery time. If you install a new program that shadows an old one, runhash -rto make bash forget. - Mint's
~/.profileadds~/binand~/.local/bintoPATHif those directories exist at login time. Create them, then log out and in again.
History and readline¶
Bash keeps a history list of the commands you type, in memory. When the shell exits, it writes the list to ~/.bash_history. Two variables control the sizes:
- HISTSIZE: how many commands to keep in memory. Mint's default
~/.bashrcsets 1000. - HISTFILESIZE: how many lines to keep in the file. Mint sets 2000.
HISTCONTROL decides what gets recorded. Mint sets it to ignoreboth, which combines:
ignorespace: commands that start with a space are not saved. Useful for commands containing passwords or tokens.ignoredups: a command identical to the previous one is not saved again.
Mint also enables shopt -s histappend, so each closing shell appends to the file instead of overwriting it. Without it, the last terminal window you close would erase the history of all the others.
Line editing in bash is provided by a library called readline. It gives you cursor movement, deletion by word, history search, and completion, using key bindings borrowed from the emacs editor by default. Text you delete with Ctrl+W, Ctrl+U, or Ctrl+K is not lost: it goes into the kill ring, and Ctrl+Y ("yank") pastes it back.
Commands and examples¶
Reusing history¶
498 cd ~/practice/text
499 grep -c ' 404 ' access.log
500 awk '$9 >= 400' access.log | wc -l
501 less access.log
502 history 5
Each entry has a number. History expansion lets you reuse entries with !:
| Syntax | Expands to | Example use |
|---|---|---|
!! |
The whole previous command | sudo !! when you forgot sudo |
!n |
Command number n | !499 |
!-2 |
The command two back | |
!grep |
The most recent command starting with grep |
|
!$ |
The last argument of the previous command | mkdir reports then cd !$ |
!* |
All arguments of the previous command | |
^old^new |
The previous command with the first old replaced by new |
Fix a typo |
!n:p |
Print command n without running it | Check before running |
Bash shows the expanded command before running it, so you can see what happened:
$ echo one two three
one two three
$ echo !$
echo three
three
$ ls /etc/hostnmae
ls: cannot access '/etc/hostnmae': No such file or directory
$ ^nmae^name
ls /etc/hostname
/etc/hostname
sudo !! is the most famous: you ran apt update, it failed with "Permission denied", and sudo !! reruns it as sudo apt update.
Hide a command from history
With Mint's HISTCONTROL=ignoreboth, start a command with a space and it is not saved: export API_TOKEN=abc123. Use it for anything containing a secret.
Searching history: Ctrl+R¶
Ctrl+R starts a reverse incremental search: type part of any earlier command, and bash shows the most recent match as you type.
(reverse-i-search)`etl': python3 etl.py --input /srv/data/raw/2026-09-21 --output /srv/data/clean --log-level debug 2>&1 | tee -a etl.log
- Press Ctrl+R again to jump to the next older match.
- Press Enter to run the match.
- Press Right or Esc to put it on the command line for editing.
- Press Ctrl+G to give up and restore the line you had.
This one shortcut is worth more than every other one in this chapter. Use it for a week and it becomes automatic.
Timestamps and bigger history¶
Add these lines to ~/.bashrc (replacing the existing HISTSIZE and HISTFILESIZE lines) for a long history with dates:
HISTTIMEFORMAT uses strftime codes: %F is the date, %T the time. A history of 50,000 commands is a few megabytes, and it turns Ctrl+R into a personal knowledge base of every command you ever figured out.
Readline shortcuts¶
| Keys | Action |
|---|---|
| Ctrl+A / Ctrl+E | Move to the start / end of the line |
| Alt+B / Alt+F | Move back / forward one word |
| Ctrl+W | Delete the word before the cursor (up to the previous space) |
| Alt+D | Delete the word after the cursor |
| Ctrl+U | Delete from the cursor to the start of the line |
| Ctrl+K | Delete from the cursor to the end of the line |
| Ctrl+Y | Paste the last deleted text |
| Ctrl+_ | Undo the last edit |
| Alt+. | Insert the last argument of the previous command (press again to cycle further back) |
| Ctrl+L | Clear the screen, keeping the current line |
| Ctrl+R | Search history backward |
| Tab / Tab Tab | Complete a name / list all completions |
| Ctrl+C | Abandon the current line (or interrupt a running command) |
| Ctrl+D | Exit the shell (on an empty line) |
| Ctrl+X Ctrl+E | Open the current line in your $EDITOR |
Some combinations that come up all the time:
- You typed a long command and realize you need something else first. Press Ctrl+U to cut the whole line, run the other command, then Ctrl+Y to paste the line back.
- You want to act on the file you just used.
ls -l reports/2026-09-21.csv, then typelessand press Alt+.. Bash insertsreports/2026-09-21.csv. - You need to fix the start of a long line. Ctrl+A, then Alt+F a few times.
Alt+. is the interactive version of !$, with the advantage that you see the text before you press Enter.
If your terminal freezes
Ctrl+S is an old terminal "pause output" signal. If your terminal suddenly stops responding to typing, you probably pressed it. Ctrl+Q resumes. Also, in the Mint terminal, Alt combinations can be taken by the menu bar; if Alt+B opens a menu, turn off the menu accelerator in the terminal's preferences, or use Esc followed by B.
Aliases¶
An alias is a shortcut: bash replaces the first word of a command with the alias text. List current aliases with alias:
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'
Those come from Mint's default ~/.bashrc. Define your own the same way (no spaces around =):
alias ..='cd ..'
alias ...='cd ../..'
alias lt='ls -lt --time-style=long-iso | head'
alias rm='rm -I'
alias df='df -h'
alias fd='fdfind'
An alias defined at the prompt lasts until the shell exits. To keep it, add it to ~/.bash_aliases (create the file if needed), which Mint's ~/.bashrc loads automatically.
To bypass an alias for one command, prefix it with a backslash or use command:
unalias name removes an alias from the current shell.
Aliases are simple text replacement at the start of a command. They cannot take arguments in the middle, contain logic, or work in scripts. When you need any of that, write a function.
Common mistake
Making dangerous commands "safe" with aliases like alias rm='rm -i' and then relying on it. On a server or inside a script, the alias does not exist, and your habit of typing rm * and expecting a prompt will bite you. rm -I (asks once) is a reasonable alias, but keep the habits from Working with files regardless.
Functions¶
A shell function is a named block of commands. Inside it, $1, $2, ... are its arguments, and "$@" is all of them. local makes a variable private to the function.
mkcd reports/2026 creates the directory and moves into it, something an alias cannot do (an alias cannot use its argument twice, and a script could not change your shell's directory).
A few functions that pay for themselves quickly:
# Top N most frequent lines from stdin or files: topn 5 < access.log
topn() {
local n="${1:-10}"
shift
sort "$@" | uniq -c | sort -rn | head -n "$n"
}
# Timestamped backup copy: bak config.ini -> config.ini.2026-09-21_1015.bak
bak() {
cp -a -- "$1" "$1.$(date +%F_%H%M).bak"
}
# Show what a command really is, and where
what() {
type -a "$1"
}
${1:-10} means "the first argument, or 10 if it is empty". shift drops the first argument so that "$@" holds only the rest (any file names). You will learn this syntax properly in Variables, quoting, and arrays and Conditionals, loops, and functions.
Put functions in ~/.bashrc. type mkcd shows a function's definition, and declare -F lists all function names.
Environment variables in practice¶
Print environment variables with printenv (or env):
EDITOR printed nothing: it is not set. declare -p shows a variable along with its attributes. -x means exported:
Prove that only exported variables reach child processes:
To set a variable for one command only, put the assignment in front of it. The variable goes into that command's environment and does not stay in your shell:
unset NAME removes a variable. export -n NAME keeps it but stops exporting it.
To make an environment variable permanent, add an export line to ~/.profile:
It takes effect at your next login. To apply it to the current shell right away, source the file (below).
Editing PATH¶
Create a personal bin directory with a small script in it:
mkdir -p ~/bin
printf '#!/bin/bash\necho "hello from my own command"\n' > ~/bin/sayhi
chmod u+x ~/bin/sayhi
sayhi
~/bin is not in PATH yet. (Mint's ~/.profile would add it, but only at login, and the directory did not exist when you logged in.) Add it for the current shell:
(For names that match a real package, Mint's command-not-found helper prints a suggestion such as Command 'hello' not found, but can be installed with: ... instead of the short message.)
The form PATH="new:$PATH" prepends: your directory is searched first. PATH="$PATH:new" appends: your directory is searched last, so system commands win.
To make it permanent, either log out and back in (the ~/.profile block handles ~/bin once it exists), or add your own line to ~/.profile for other directories:
Common mistake
Writing PATH=~/bin (without :$PATH). That replaces the whole search path, and suddenly ls, grep, and everything else are "command not found" in that shell. If it happens, open a new terminal, or repair it with export PATH=/usr/local/bin:/usr/bin:/bin and fix the file.
Customizing the prompt: PS1¶
The prompt is the value of the PS1 variable, with special backslash escapes:
| Escape | Shows |
|---|---|
\u |
Username |
\h |
Hostname up to the first dot |
\w |
Current directory, with ~ for home |
\W |
Only the last part of the current directory |
\$ |
$ for normal users, # for root |
\t / \A |
Time as HH:MM:SS / HH:MM |
\j |
Number of background jobs |
\n |
Newline |
Mint's default prompt is equivalent to \u@\h:\w\$ with colors, which displays as:
Try alternatives in the current shell. They last until you close it:
Colors use terminal escape codes. Wrap each code in \[ and \] so bash knows those characters take no space on screen; without them, long lines wrap in the wrong place. \e[32m is green, \e[34m blue, \e[31m red, \e[1m bold, and \e[0m resets:
A useful upgrade is showing the exit status of the last command when it failed. PROMPT_COMMAND holds commands that bash runs just before printing each prompt:
__prompt_status() {
local code=$?
if [ "$code" -ne 0 ]; then PS1_STATUS="[$code] "; else PS1_STATUS=""; fi
}
PROMPT_COMMAND="__prompt_status${PROMPT_COMMAND:+; $PROMPT_COMMAND}"
PS1='\[\e[31m\]${PS1_STATUS}\[\e[0m\]\[\e[32m\]\u@\h\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]\$ '
The single quotes around PS1 matter: ${PS1_STATUS} must be expanded each time the prompt is drawn, not once when you set it. The ${PROMPT_COMMAND:+; ...} part keeps any PROMPT_COMMAND that Mint's terminal already set.
If git is installed, Mint also ships /usr/lib/git-core/git-sh-prompt, which provides __git_ps1 to show the current branch in your prompt. Its usage is documented at the top of that file.
When you are happy, copy your PS1 lines into ~/.bashrc, after the default PS1 block so they override it.
source: run a file in the current shell¶
Running a script starts a new bash process. Anything it sets (variables, aliases, cd) disappears when it exits. source file (or its short form, . file) instead reads the file and runs its commands in your current shell:
flowchart LR
A["./setenv.sh"] --> B["new child bash<br/>sets variables<br/>exits: changes lost"]
C["source setenv.sh"] --> D["current shell<br/>runs each line<br/>changes stay"]
printf 'export DATA_DIR=/srv/data\nalias ymd="date +%%F"\n' > ~/practice/setenv.sh
bash ~/practice/setenv.sh; echo "after running: [$DATA_DIR]"
source ~/practice/setenv.sh; echo "after sourcing: [$DATA_DIR]"
ymd
(If you exported DATA_DIR earlier in this chapter, run unset DATA_DIR first to see the difference.)
You will use source constantly after editing your configuration:
That applies your changes to the current terminal without opening a new one. Python virtual environments use the same mechanism: source .venv/bin/activate modifies your current shell's PATH and prompt.
Putting it together: a starter ~/.bashrc block¶
Open ~/.bashrc with nano ~/.bashrc, scroll to the end, and add a clearly marked section. Keep your additions together so you can find and copy them to other machines:
# ---- my additions ----
HISTSIZE=50000
HISTFILESIZE=100000
HISTTIMEFORMAT='%F %T '
shopt -s globstar # ** matches directories recursively
alias ..='cd ..'
alias lt='ls -lt --time-style=long-iso | head'
alias rm='rm -I'
mkcd() { mkdir -p -- "$1" && cd -- "$1"; }
topn() { local n="${1:-10}"; shift; sort "$@" | uniq -c | sort -rn | head -n "$n"; }
Then add environment variables to ~/.profile:
Apply with source ~/.bashrc (and log out and in for ~/.profile). If something breaks, a typo in ~/.bashrc can make every new terminal print errors; open the file with nano and fix it, or start a clean shell with bash --norc to investigate.
Exercises¶
Exercise 1: History drills (easy)¶
Run mkdir -p ~/practice/hist/a/b. Then, without retyping the path: (a) cd into it using !$, (b) list its parent with ls and Alt+. followed by editing, (c) find the mkdir command with Ctrl+R and print it without running it.
Solution
For (b), type ls and press Alt+.. Bash inserts the last argument of the previous command, ~/practice/hist/a/b (the cd !$ line was stored in history in its expanded form, cd ~/practice/hist/a/b). Press Backspace twice to remove /b, then Enter. Do not use Ctrl+W here: it deletes back to the previous space, which would remove the whole path.
For (c), press Ctrl+R, type mkdir, then press Esc to place the command on the line without running it. Alternatively, !mkdir:p prints the most recent mkdir command without executing it.
Exercise 2: Shell variable or environment variable? (easy)¶
Set CITY=Pune without exporting it. Show that a child bash cannot see it, then export it and show that it can. Finally, run env for one command with CITY=Delhi and show that your shell's value is unchanged.
Solution
CITY=Pune
bash -c 'echo "child: [$CITY]"'
export CITY
bash -c 'echo "child: [$CITY]"'
CITY=Delhi bash -c 'echo "child: [$CITY]"'
echo "shell: [$CITY]"
The prefix assignment only applied to that one command's environment.
Exercise 3: Your first useful function (medium)¶
Write a function logtail that takes a file name and an optional number of lines (default 20), and shows the last N lines with line numbers. Add it to ~/.bashrc, reload, and test it on ~/practice/text/access.log. Check where bash finds it with type.
Solution
Add to ~/.bashrc:
1 198.51.100.7 - - [21/Sep/2026:11:03:33 +0000] "GET /products/42 HTTP/1.1" 304 0 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 17_4) Safari/604.1"
2 192.0.2.33 - - [21/Sep/2026:11:04:59 +0000] "GET /api/products?page=2 HTTP/1.1" 200 1893 "-" "python-requests/2.31.0"
logtail is a function
logtail ()
{
local file="$1" n="${2:-20}";
tail -n "$n" -- "$file" | cat -n
}
type prints the function body as bash stored it.
Exercise 4: A personal bin directory (medium)¶
Create ~/bin/today that prints the date as YYYY-MM-DD. Make it runnable as today from any directory, now and after you log in again. Then make an alias today that prints ALIAS, and use type -a today to show which one wins and why. Remove the alias afterwards.
Solution
mkdir -p ~/bin
printf '#!/bin/bash\ndate +%%F\n' > ~/bin/today
chmod u+x ~/bin/today
export PATH="$HOME/bin:$PATH" # now; ~/.profile adds ~/bin at future logins
today
alias today='echo ALIAS'
type -a today
unalias today
Aliases are checked before PATH, so the alias wins. %% in printf produces a literal %. Mint's ~/.profile adds ~/bin to PATH at login whenever the directory exists, so no further edit is needed.
Exercise 5: Diagnose the vanishing aliases (hard)¶
Reproduce the story from "Why it matters" safely: create ~/.bash_profile containing only export DATA_DIR=/srv/data, then start a login shell with bash -l and check whether your aliases work. Explain the result, fix ~/.bash_profile so login shells behave correctly, and verify. Finally, remove the file if you do not need it.
Solution
A login shell reads only the first existing file among ~/.bash_profile, ~/.bash_login, and ~/.profile. Now that ~/.bash_profile exists, ~/.profile is skipped, and with it the block that sources ~/.bashrc, where the aliases live. Type exit to leave the test shell.
Fix: make ~/.bash_profile load ~/.profile first.
cat > ~/.bash_profile <<'EOF'
[ -f ~/.profile ] && . ~/.profile
export DATA_DIR=/srv/data
EOF
bash -l
type ll
echo "$DATA_DIR"
exit
Simpler still: delete ~/.bash_profile (rm ~/.bash_profile) and put export DATA_DIR=/srv/data in ~/.profile, which is where Mint expects it.
Check yourself¶
-
Is a new terminal window on the Mint desktop a login shell? Which of your files does it read?
Answer
No, it is an interactive non-login shell. It reads
/etc/bash.bashrcand~/.bashrc. (Your desktop session itself was started through~/.profile.) -
Why don't your aliases work inside a script?
Answer
Scripts run in a non-interactive shell, which reads no startup files, so
~/.bashrcis never loaded. Also, alias expansion is off by default in non-interactive shells. Scripts should use full commands or functions defined in the script. -
What is the difference between
x=1andexport x=1?Answer
Both create a variable in the current shell.
exportalso marks it to be copied into the environment of every command the shell starts. Without it, child processes do not seex. -
What do
!!,!$, and^old^newdo?Answer
!!repeats the previous command,!$is the last argument of the previous command, and^old^newreruns the previous command with the firstoldreplaced bynew. -
What do
HISTCONTROL=ignorebothandhistappendgive you?Answer
ignorebothskips saving commands that start with a space and consecutive duplicates.histappendmakes each shell append its history to~/.bash_historyon exit, instead of overwriting it, so several terminals do not erase each other's history. -
What do Ctrl+W, Ctrl+U, Ctrl+K, and Alt+. do?
Answer
Delete the word before the cursor, delete to the start of the line, delete to the end of the line, and insert the last argument of the previous command. Deleted text can be pasted back with Ctrl+Y.
-
Why does
./setenv.shnot change your shell's variables, whilesource setenv.shdoes?Answer
./setenv.shruns in a child process; its changes die with it, and a child cannot modify its parent's environment.sourceruns the commands in the current shell. -
What is wrong with
PATH=~/bin, and what should you write instead?Answer
It replaces the whole search path, so system commands can no longer be found. Write
export PATH="$HOME/bin:$PATH"to prepend, or"$PATH:$HOME/bin"to append.
Key takeaways¶
- Ctrl+R for history search, Alt+. for the last argument, and Ctrl+A/Ctrl+E/Ctrl+W/Ctrl+U for editing will save you hours.
- Login shells read
/etc/profileand the first of~/.bash_profile,~/.bash_login,~/.profile. Interactive non-login shells read~/.bashrc. Scripts read neither. - Environment variables (and
PATH) go in~/.profile; aliases, functions, prompt, and history settings go in~/.bashrc. exportcopies a variable into children's environments; children can never change the parent's variables.VAR=value cmdsets it for one command.PATHis searched left to right; prepend your own directories withPATH="$HOME/bin:$PATH".- Aliases are text shortcuts; functions take arguments and can change the current shell.
sourceruns a file in the current shell. Use it to reload~/.bashrc.
Next¶
Next, learn to bundle, compress, and verify files with tar, gzip, and friends: Archives and compression. When you have finished the level's chapters, prove your skills in the Level 1 capstone.