Mastering Linux: From Foundation to Application
Command-Line Proficiency
Smarter Navigation
You already know how to get around with cd and ls. But when you're jumping between several directories, typing paths over and over gets tedious. The command line offers a more elegant way to handle this: the directory stack.
Think of the directory stack like a stack of plates. The pushd command adds a directory to the top of the stack and automatically navigates into it. The popd command removes the top directory and takes you to the new one at the top.
# Let's say we are in our home directory (~)
# Push /var/log onto the stack and cd into it
pushd /var/log
# Push /etc/nginx onto the stack and cd into it
pushd /etc/nginx
# See the current stack. The top is on the left.
dirs -v
# Output:
# 0 /etc/nginx
# 1 /var/log
# 2 ~
# Pop /etc/nginx and return to /var/log
popd
# Pop /var/log and return home
popd
For quickly jumping between your current and previous directory, there's an even faster shortcut.
Use
cd -to instantly switch back to the last directory you were in.
Manipulating Files with Precision
Creating, moving, and copying files is just the beginning. True command-line proficiency comes from finding and manipulating files based on specific criteria. For this, the find command is indispensable. It searches for files in a directory hierarchy based on rules you define.
# Find all files ending with .log in the current directory and subdirectories
find . -name "*.log"
# Find all directories modified in the last 2 days
find /home/user/documents -type d -mtime -2
The real power of find comes from combining it with other commands. The -exec option lets you run any command on each file that find discovers.
# Find all temporary files (*.tmp) and delete them
find . -name "*.tmp" -exec rm {} \;
In the command above,
{}is a placeholder thatfindreplaces with the name of each file it finds. The\;tellsfindwhere the command ends.
Another essential tool is grep, which scans files for lines containing a matching pattern. You can use it to quickly locate specific information within log files, code, or any text-based data.
# Search for the word "error" in a log file
grep "error" /var/log/syslog
# Search for the same word, but ignore case and show line numbers
grep -in "error" /var/log/syslog
Connecting Commands
In Linux, programs are designed to do one thing well. The magic happens when you connect these simple tools to perform complex tasks. This is done using streams, pipes, and redirection.
Every command-line program has three standard streams:
stdin(Standard Input): Where the program gets its input. By default, this is your keyboard.stdout(Standard Output): Where the program sends its normal output. By default, this is your screen.stderr(Standard Error): Where the program sends error messages. This also goes to your screen by default.
Redirection allows you to change where these streams go. You can save a command's output to a file instead of displaying it, or have a program read from a file instead of the keyboard.
| Operator | Name | Description |
|---|---|---|
> | Redirect | Sends stdout to a file, overwriting it. |
>> | Append Redirect | Appends stdout to a file. |
< | Input Redirect | Reads stdin from a file. |
2> | Error Redirect | Redirects stderr to a file. |
# Save the list of files to files.txt, overwriting it
ls -l > files.txt
# Add a disk usage report to the end of files.txt
du -h >> files.txt
# Sort the contents of users.txt
sort < users.txt
# Run a script and save any errors to error.log
./my_script.sh 2> error.log
Pipes are even more powerful. A pipe, represented by the | symbol, takes the stdout of one command and sends it directly to the stdin of another command. This lets you chain commands together, with the output of one becoming the input for the next.
Think of pipes as an assembly line for your data.
# List all processes running on the system
ps aux
# Find the line for the 'nginx' process from the full list
ps aux | grep nginx
Here, ps aux produces a list of all running processes. Instead of printing to the screen, the pipe sends that entire list to grep, which then filters it and only prints the lines containing "nginx". You've combined two simple utilities to create a precise tool.
Let's look at a more complex example. Imagine you want to find the 10 most common commands you've ever used.
history | awk '{print $2}' | sort | uniq -c | sort -rn | head -n 10
This might look intimidating, but it's just a chain of simple steps:
history: Lists your command history.awk '{print $2}': Prints only the second column (the command name) for each line.sort: Sorts the list of commands alphabetically.uniq -c: Counts consecutive identical lines.sort -rn: Sorts the counted list numerically (-n) and in reverse (-r) order.head -n 10: Shows only the top 10 lines of the result.
By mastering pipes and redirection, you can build sophisticated data-processing workflows directly on the command line, using simple, reliable tools as your building blocks.
What is the primary function of the pushd command?
Which symbol is used to create a pipe, sending the standard output of one command to the standard input of another?
These techniques form the foundation for efficient work in any command-line environment.