Tag: CLI

  • Squashing Commits in Git: Cleaning Up Your Project History

    Squashing Commits in Git: Cleaning Up Your Project History

    If you’ve ever ended up with a heap of noisy, work-in-progress (WIP) commits after a coding sprint, you know how messy a project’s commit history can get. Maintaining a clean, readable Git log is critical—especially for collaborative work and open source contributions. Today, I want to walk you through the powerful Git technique of "squashing commits," helping you present a tidy project history without losing important changes.

    Why Squash Commits?

    Squashing is the act of combining multiple consecutive commits into one. This is often used during a Git rebase to clean up a feature branch before merging it into main. It’s particularly helpful for:

    • Reducing noise: Fewer, more meaningful commits make it easier to track project history.
    • Improving clarity: Each squashed commit can reflect a well-defined change or feature.
    • Facilitating code reviews: Reviewers appreciate concise, logical changesets.

    How to Squash Commits

    There are a few ways to squash commits in Git, but the most common method is interactive rebase. Here’s a quick guide:

    1. Start Interactive Rebase

    git rebase -i HEAD~N
    

    Replace N with the number of commits you want to squash (e.g., HEAD~3 for the last 3 commits).

    2. The Interactive Screen

    Your default editor will open a list of the last N commits:

    pick 1a2b3c4 Add initial feature blueprint
    pick 2b3c4d5 Implement feature logic
    pick 3c4d5e6 Fix bug in feature
    

    Change all but the first pick to squash or simply s:

    pick 1a2b3c4 Add initial feature blueprint
    squash 2b3c4d5 Implement feature logic
    squash 3c4d5e6 Fix bug in feature
    

    3. Write a Commit Message

    Git will now prompt you to update the commit message for your new, squashed commit. You can combine all messages, summarize, or write a new concise description.

    4. Complete the Rebase

    Save and close the editor. Git will process the rebase and squash your selected commits into one.

    Best Practices for Squashing Commits

    • Communicate with your team before rebasing shared branches—rewriting history can impact collaborators.
    • Squash in feature branches before merging into main/trunk.
    • Use --autosquash with rebase if you’ve used fixup! or squash! commit prefixes.

    Wrapping Up

    Squashing commits is an essential Git technique for any developer seeking a clean and understandable history. It’s easy to adopt into your workflow and will vastly improve your team’s experience during code reviews and when tracing changes.

    Want more advanced tips? Check out my other articles on Git workflows and histories—let’s keep our repos as clean as our code!

    Happy coding!

    — Joe Git

  • Efficient Log Analysis on Apache Web Servers Using the Command Line

    Efficient Log Analysis on Apache Web Servers Using the Command Line

    As a Linux server administrator, keeping track of your Apache Web Server’s activity and performance is essential. Apache’s robust logging facilities (access and error logs) can hold crucial information about visitor traffic, possible attacks, and performance bottlenecks. But those log files can grow massive — so reading them efficiently from the command line is a must-have skill for every sysadmin. In this article, I’ll run through some of the most effective command-line techniques for analyzing Apache logs.

    Locating Apache Log Files

    By default, Apache keeps log files in /var/log/apache2/ (Debian/Ubuntu) or /var/log/httpd/ (CentOS/RHEL). Typical files are:

    • access.log: Every request to your server.
    • error.log: Errors and diagnostic messages.

    Basic Log Viewing

    To check the most recent log entries:

    tail -n 50 /var/log/apache2/access.log
    

    The above displays the last 50 lines. To watch updates in real time (e.g., as traffic comes in):

    tail -f /var/log/apache2/access.log
    

    Filtering Log Entries

    Let’s say you’re concerned about a particular IP or URL. You can filter log entries like so:

    grep "203.0.113.42" /var/log/apache2/access.log
    

    Or, to find out which URLs were most requested:

    awk '{print $7}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -20
    

    This command breaks down as follows:

    • awk '{print $7}' extracts the request path.
    • sort | uniq -c groups and counts each URL.
    • sort -nr sorts them by popularity.
    • head -20 shows the top 20.

    Spotting Errors Quickly

    Error logs are invaluable for debugging. To see the last few error messages:

    tail -n 100 /var/log/apache2/error.log
    

    To find all lines containing “segfault” (a sign of a potentially serious bug):

    grep segfault /var/log/apache2/error.log
    

    Summarizing Traffic by Status Code

    Want a quick traffic health-check? This command shows the most common HTTP responses:

    awk '{print $9}' /var/log/apache2/access.log | sort | uniq -c | sort -nr
    

    The $9 field is HTTP status (e.g., 200, 404, etc.).

    Advanced: Combining Tools for Insight

    You can chain commands for deeper insights. For example, to see which IPs are generating the most 404 (Not Found) errors:

    grep ' 404 ' /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head
    

    Tips for Handling Huge Logs

    • Consider using zcat, zgrep, or zless on rotated and compressed logs (ending in .gz).
    • Use sed or awk to extract date ranges or fields if your logs get enormous.

    Mastering these command-line techniques will make you more efficient at troubleshooting, spotting anomalies, and understanding visitor patterns. Apache’s logs are a goldmine — and with the CLI, you’ve got the right pickaxe.

    Happy logging!

    Lenny

  • Demystifying Git Clean: Safely Tidying Up Your Working Directory

    Demystifying Git Clean: Safely Tidying Up Your Working Directory

    When working on complex projects, it’s easy for your Git working directory to accumulate a lot of unnecessary files—build artifacts, temporary logs, and experiment leftovers. If you’ve ever wondered how to quickly clean things up without accidentally losing important work, Git’s git clean command is here to help. In this article, I’ll walk you through how git clean works, how to use it responsibly, and a few pro tips to keep your project environment tidy.

    What Does git clean Do?

    Put simply, git clean removes untracked files and directories from your working directory. These are files that are not being tracked by Git (i.e., files not listed in your index or .gitignore). This can be a lifesaver when you want to get back to a pristine state.

    Basic Usage

    The simplest usage is:

    git clean -n
    

    This does a “dry run”—it lists the files that would be removed, without deleting anything. Always start with this!

    To actually remove untracked files:

    git clean -f
    

    If you want to remove untracked directories as well:

    git clean -fd
    

    Combine with the -x flag if you want to also remove files ignored by .gitignore:

    git clean -fdx
    

    Be very careful with -x. You can lose local config files and other important ignored files.

    Pro Tips for Safe Cleaning

    1. Always Use Dry Run First: Run git clean -n (or --dry-run) to see what will happen before you actually delete anything.
    2. Be Specific: Use git clean -f path/to/file to remove only certain files or folders.
    3. Integrate with Your Workflow: Combine it with git stash or git reset --hard to completely revert your repo to the last committed state.

    Common Use Cases

    • Build Artifacts: Get rid of untracked binaries and compiled files before a new build.
    • Experimentation: Clean up temporary files after testing out new ideas.
    • PR Preparation: Tidy your repo before submitting a pull request.

    Conclusion

    git clean is a powerful command to keep your repository organized, but with great power comes great responsibility. Always double-check what you’re deleting and, when in doubt, back up important files. With these tips, you can work more confidently and maintain a clean development environment—one less thing to worry about!

    Happy coding!

    – Joe Git

  • Mastering the ‘top’ Command: Tips for Efficient Linux Server Monitoring

    Mastering the ‘top’ Command: Tips for Efficient Linux Server Monitoring

    When it comes to monitoring the health and performance of your Linux servers, the "top" command is often one of the first tools in an administrator’s arsenal. It provides a real-time, dynamic view of what’s happening on your system, including which processes are consuming the most resources and overall system load. Yet, many users only scratch the surface of what "top" can do. This article explores some practical tips and advanced usage that can help you get the most out of the "top" command.

    Basic Usage

    Simply typing top in your terminal brings up a continually updating table of processes. Here you’ll see columns for PID, user, CPU and memory usage, and more. The header section shows system uptime, load averages, and summary information about memory and processes.

    Navigating and Customizing the Display

    • Sorting by column: You can change how processes are sorted. Press P to sort by CPU usage or M to sort by memory usage. For other columns, press Shift + <column key> and watch the table update accordingly.
    • Changing update interval: Press d and enter a new number of seconds to set the screen refresh rate. A longer interval can lessen system load on heavily used servers.
    • Filtering processes: Hit o (lowercase letter o), then type a filter (e.g., USER=apache to see only apache processes).
    • Killing a process: Press k, type the PID of the process, and then the signal (usually 15 for gracefully terminating, or 9 for forcefully ending).

    Useful Command-Line Options

    • Display specific user’s processes: top -u someuser
    • Show only processes with high resource use: Combine with grep or use interactive filters in "top" to focus on processes hogging resources.

    Saving Custom Options

    You can customize the top interface (like adjusting columns and sorting), then press W (capital w) to save your preferred configuration for future sessions.

    Advanced Tips

    • Batch mode (for logs and scripting): top -b -n 1 > top-output.txt runs top in batch mode, which is useful for logging system state or integrating into other scripts.
    • Highlighting active processes: Press z to toggle color highlighting of the most active processes.
    • Tree view: Press V to view the processes in a hierarchical tree mode, showing parent/child relationships.

    Conclusion

    The "top" command is a foundational monitoring tool for Linux server administrators. By mastering its interactive features, command-line options, and customizations, you can gain critical insights into your server’s health and performance—ensuring your hosted web sites and services run smoothly.

    Whether you’re a beginner or a seasoned sysadmin, spending some time with "top" can make all the difference in proactive server management.

  • Securing Apache Web Server: Essential Command-Line Techniques

    Securing Apache Web Server: Essential Command-Line Techniques

    When it comes to hosting web sites on Linux servers, security is always a top priority. While Apache is a robust and reliable web server, its security out-of-the-box typically needs enhancement to withstand modern threats. In this article, I’ll walk you through essential command-line techniques to secure your Apache installation and reduce potential attack surfaces, drawing on my experience managing Linux-based web hosting environments.

    1. Keep Apache and Dependencies Updated

    Running outdated software is a common vulnerability. Update your Apache installation and its dependencies with:

    sudo apt update && sudo apt upgrade apache2   # Debian/Ubuntu
    sudo yum update httpd                        # CentOS/RedHat
    

    Automate this with unattended-upgrades or a systemd timer (see my article on systemd timers for more details).

    1. Disable Unused Apache Modules

    Apache has a modular architecture. Only load what you need:

    sudo apache2ctl -M                      # List enabled modules
    sudo a2dismod autoindex                 # Example for Debian/Ubuntu
    

    After disabling, reload:

    sudo systemctl reload apache2
    

    On RHEL/CentOS, you may need to comment out modules in httpd.conf.

    1. Restrict Directory Permissions

    Use minimal permissions and ownership for web directories. For example:

    sudo chown -R www-data:www-data /var/www/html
    sudo find /var/www/html -type d -exec chmod 750 {} \;
    sudo find /var/www/html -type f -exec chmod 640 {} \;
    
    1. Configure Apache Security Settings

    Edit your main config (often /etc/apache2/apache2.conf or /etc/httpd/conf/httpd.conf) and consider:

    # Hide server version details
    ServerSignature Off
    ServerTokens Prod
    
    # Limit request size to mitigate some DoS attacks
    LimitRequestBody 1048576
    
    # Disable directory listing
    <Directory /var/www/html>
        Options -Indexes
    </Directory>
    
    1. Enable TLS/SSL

    Secure traffic with HTTPS using Let’s Encrypt:

    sudo apt install certbot python3-certbot-apache
    sudo certbot --apache
    

    Certbot configures SSL automatically, but be sure to set strong ciphers and protocols. Example in ssl.conf:

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5
    SSLHonorCipherOrder on
    
    1. Monitor Logs Regularly

    Automate log checks with tools like fail2ban, and inspect logs on the command line:

    tail -f /var/log/apache2/access.log /var/log/apache2/error.log
    

    Conclusion

    By applying these straightforward command-line techniques, you can lock down your Apache web server and help protect your web sites against common vulnerabilities. Stay proactive—monitor updates, prune what’s unnecessary, and automate where possible for a safer, more resilient hosting environment.

  • Managing Shell History in Unix: Bash and Beyond

    Managing Shell History in Unix: Bash and Beyond

    On Linux servers, the command line is king—and as you work in a Unix environment, your command history becomes an invaluable asset. Yet, many sysadmins and developers aren’t aware of the subtle (and not-so-subtle) differences in how shells like Bash, Zsh, and others manage their history files. This article explores how history management works across common shell environments, with a focus on Bash, and offers tips for boosting security and efficiency on your server.

    Bash: The Most Common Shell

    The Bourne Again SHell (Bash) is the default shell for many Linux distributions. Its history management is robust and highly configurable:

    • History File: Bash stores your command history in ~/.bash_history, though this can be customized by setting the $HISTFILE variable.
    • Session and File: Commands are kept in RAM until you exit the shell; then, they are written to the history file. You can force an update with the history -a and history -w commands.
    • Concurrency: Before Bash 5, concurrent (simultaneous) sessions could overwrite history. Modern versions support the histappend option (shopt -s histappend) and the PROMPT_COMMAND="history -a; history -n" trick to avoid losing commands between sessions.
    • Configuration: Variables like HISTSIZE (in-memory size) and HISTFILESIZE (on disk) define limits. Sensitive data can be excluded with the HISTIGNORE and HISTCONTROL variables.

    Zsh: Feature-Rich History

    Zsh has a more advanced history system, and it’s become popular for its customization:

    • Default File: Zsh saves history in ~/.zsh_history.
    • Incremental Updates: Zsh writes each command immediately (with the INC_APPEND_HISTORY option), preventing loss between sessions.
    • Shared History: Use setopt SHARE_HISTORY to synchronize history across all running sessions in real time.

    Other Shells: sh, ksh, fish

    • sh/dash: Basic Bourne dashboards (like /bin/sh or dash) typically lack user-specific history.
    • ksh (KornShell): Similar to Bash, but with different default paths (e.g., ~/.sh_history).
    • fish: The Friendly Interactive Shell stores history in a human-readable YAML file (~/.local/share/fish/fish_history), auto-updating as you go.

    Tips for Effective History Management

    1. Don’t Log Sensitive Data: Set HISTCONTROL=ignorespace and start sensitive commands with a space, or configure HISTIGNORE to skip certain patterns (like *password*).
    2. Increase Size Limits: Bump up HISTSIZE and HISTFILESIZE for longer recall.
    3. Clear or Edit History: Use history -d <line_number> (Bash) to delete problematic entries, or simply edit the history file.
    4. Search Efficiently: Press Ctrl+R for reverse search, or use grep on your .bash_history for deeper dives.

    Conclusion

    Different shells have different philosophies and defaults for history management, and understanding these subtleties is key for both productivity and security. Whether you’re tailoring .bashrc or .zshrc, a little configuration goes a long way. Master your shell history, and you’ll become a more effective sysadmin or developer—one command at a time.